Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (200066 => 200067)
--- trunk/Source/WebInspectorUI/ChangeLog 2016-04-26 00:50:07 UTC (rev 200066)
+++ trunk/Source/WebInspectorUI/ChangeLog 2016-04-26 01:00:17 UTC (rev 200067)
@@ -1,3 +1,198 @@
+2016-04-25 Matt Baker <[email protected]>
+
+ Web Inspector: hook up grid row filtering in the new Timelines UI
+ https://bugs.webkit.org/show_bug.cgi?id=154924
+ <rdar://problem/24934607>
+
+ Reviewed by Timothy Hatcher.
+
+ Re-implement timeline data grid filtering that previously existed in the
+ navigation sidebar. This patch adds support for filter text, scope bars,
+ and filtering based on ruler selection.
+
+ Multi-column filter support is now part of DataGrid. The grid checks compares
+ filter text against cell data of type string. DataGridNode subclasses may
+ provide custom string data for columns that format complex objects (such
+ as SourceCodeLocations). Cells containing data of type number are not
+ considered for filtering at this time.
+
+ * UserInterface/Views/DataGrid.js:
+ (WebInspector.DataGrid):
+ (WebInspector.DataGrid.prototype.set filterText):
+ (WebInspector.DataGrid.prototype.get filterDelegate):
+ (WebInspector.DataGrid.prototype.set filterDelegate):
+ (WebInspector.DataGrid.prototype.filterDidChange):
+ Called internally by the grid whenever the filter text or delegate changes.
+ Also called by clients that implement a filter delegate, to inform the
+ grid that a custom filter has changed.
+
+ (WebInspector.DataGrid.prototype.hasCustomFilters):
+ (WebInspector.DataGrid.prototype.matchNodeAgainstCustomFilters):
+ Calls the filter delegate, if it exists, and provides a hook for
+ subclasses to provide custom filtering.
+
+ (WebInspector.DataGrid.prototype._applyFiltersToNode.matchTextFilter):
+ (WebInspector.DataGrid.prototype._applyFiltersToNode.makeVisible):
+ (WebInspector.DataGrid.prototype._applyFiltersToNode):
+ Filters data grid nodes and fires filter events as needed.
+ (WebInspector.DataGrid.prototype._hasFilterDelegate):
+ Helper function.
+ (WebInspector.DataGrid.prototype._updateVisibleRows):
+ Exclude hidden nodes from revealed rows.
+ (WebInspector.DataGrid.prototype._updateFilter):
+ Filtering entry point, called on an animation frame. Updates visible
+ rows if any node was filtered/unfiltered.
+
+ (WebInspector.DataGridNode):
+ (WebInspector.DataGridNode.prototype.get filterableData):
+ Gets an array of filterable strings for the node.
+ (WebInspector.DataGridNode.prototype.refresh):
+ Resets cached filterable strings.
+ (WebInspector.DataGridNode.prototype.filterableDataForColumn):
+ Can be overridden by subclasses to provide filterable text for complex
+ cell data, like as objects formatted as document fragments.
+
+ * UserInterface/Views/LayoutTimelineDataGridNode.js:
+ (WebInspector.LayoutTimelineDataGridNode.prototype.get data):
+
+ * UserInterface/Views/LayoutTimelineView.js:
+ (WebInspector.LayoutTimelineView):
+ Register grid and remove logic that has been moved to the base class.
+ (WebInspector.LayoutTimelineView.prototype.filterDidChange):
+ Update highlight after grid filter change.
+ (WebInspector.LayoutTimelineView.prototype._dataGridSelectedNodeChanged):
+ Update highlight when selection changes.
+ (WebInspector.LayoutTimelineView.prototype.matchTreeElementAgainstCustomFilters): Deleted.
+ (WebInspector.LayoutTimelineView.prototype.treeElementDeselected): Deleted.
+ (WebInspector.LayoutTimelineView.prototype._dataGridFiltersDidChange): Deleted.
+ (WebInspector.LayoutTimelineView.prototype._dataGridNodeSelected): Deleted.
+ No longer needed.
+
+ * UserInterface/Views/NetworkTimelineView.js:
+ (WebInspector.NetworkTimelineView):
+ Register grid and remove logic that has been moved to the base class.
+ (WebInspector.NetworkTimelineView.prototype.matchTreeElementAgainstCustomFilters): Deleted.
+ (WebInspector.NetworkTimelineView.prototype._dataGridFiltersDidChange): Deleted.
+ (WebInspector.NetworkTimelineView.prototype._dataGridNodeSelected): Deleted.
+ No longer needed.
+
+ * UserInterface/Views/OverviewTimelineView.js:
+ (WebInspector.OverviewTimelineView):
+ Register grid and remove logic that has been moved to the base class.
+ (WebInspector.OverviewTimelineView.prototype._dataGridNodeSelected): Deleted.
+ No longer needed.
+
+ * UserInterface/Views/RenderingFrameTimelineView.js:
+ (WebInspector.RenderingFrameTimelineView):
+ Register grid and remove logic that has been moved to the base class.
+ (WebInspector.RenderingFrameTimelineView.prototype.get filterStartTime):
+ (WebInspector.RenderingFrameTimelineView.prototype.get filterEndTime):
+ Convert selection indices into filter start and end times.
+ (WebInspector.RenderingFrameTimelineView.prototype.matchDataGridNodeAgainstCustomFilters):
+ Perform custom filtering on rendering frame duration.
+ (WebInspector.RenderingFrameTimelineView.prototype._scopeBarSelectionDidChange):
+ Inform grid of custom filter change.
+ (WebInspector.RenderingFrameTimelineView.prototype.matchTreeElementAgainstCustomFilters): Deleted.
+ (WebInspector.RenderingFrameTimelineView.prototype._dataGridNodeSelected): Deleted.
+ No longer needed.
+
+ * UserInterface/Views/ResourceTimelineDataGridNode.js:
+ (WebInspector.ResourceTimelineDataGridNode.prototype.filterableDataForColumn):
+ Use URL string for filtering "name" column.
+
+ * UserInterface/Views/ScriptClusterTimelineView.js:
+ (WebInspector.ScriptClusterTimelineView.prototype.updateFilter):
+ Forwarding for TimelineView API.
+ (WebInspector.ScriptClusterTimelineView.prototype.matchDataGridNodeAgainstCustomFilters):
+ (WebInspector.ScriptClusterTimelineView.prototype.matchTreeElementAgainstCustomFilters): Deleted.
+ Renamed to matchDataGridNodeAgainstCustomFilters.
+ (WebInspector.ScriptClusterTimelineView.prototype._scriptClusterViewCurrentContentViewDidChange): Deleted.
+ Removed FIXME comment. Updating TimelineView times is sufficient to trigger filtering.
+
+ * UserInterface/Views/ScriptDetailsTimelineView.js:
+ (WebInspector.ScriptDetailsTimelineView):
+ Register grid and remove logic that has been moved to the base class.
+ (WebInspector.ScriptDetailsTimelineView.prototype._dataGridFiltersDidChange): Deleted.
+ (WebInspector.ScriptDetailsTimelineView.prototype._dataGridNodeSelected): Deleted.
+ No longer needed.
+
+ * UserInterface/Views/ScriptTimelineDataGridNode.js:
+ (WebInspector.ScriptTimelineDataGridNode.prototype.filterableDataForColumn):
+ Use main title and subtitle strings for filtering "name" column.
+ (WebInspector.ScriptTimelineDataGridNode.prototype._createNameCellDocumentFragment):
+ (WebInspector.ScriptTimelineDataGridNode.prototype._subtitle):
+ Break out for use in filterableDataForColumn.
+
+ * UserInterface/Views/TimelineDataGrid.js:
+ (WebInspector.TimelineDataGrid):
+ Cleanup variable names.
+ (WebInspector.TimelineDataGrid.prototype.hasCustomFilters):
+ Always true because filtering on ruler selection always occurs.
+ (WebInspector.TimelineDataGrid.prototype.matchNodeAgainstCustomFilters):
+ Match nodes against scope bar filters.
+ (WebInspector.TimelineDataGrid.prototype._scopeBarSelectedItemsDidChange):
+ Inform grid of custom filter change.
+ (WebInspector.TimelineDataGrid.prototype.treeElementMatchesActiveScopeFilters): Deleted.
+ Re-implemented as _nodeMatchesActiveScopeFilters.
+ (WebInspector.TimelineDataGrid.prototype._updateScopeBarForcedVisibility): Deleted.
+ Old UI. No longer needed.
+
+ * UserInterface/Views/TimelineDataGridNode.js:
+ (WebInspector.TimelineDataGridNode.prototype.filterableDataForColumn):
+ Filter strings for SourceCodeLocation and CallFrame objects.
+
+ * UserInterface/Views/TimelineRecordingContentView.js:
+ (WebInspector.TimelineRecordingContentView):
+ Listen for FilterBar changes and TimelineView record filtering.
+ (WebInspector.TimelineRecordingContentView.prototype._filterDidChange):
+ Update grid filters when filter bar changes.
+ (WebInspector.TimelineRecordingContentView.prototype._recordWasFiltered):
+ Update overview when records are filtered/unfiltered.
+ (WebInspector.TimelineRecordingContentView.prototype.filterDidChange): Deleted.
+ (WebInspector.TimelineRecordingContentView.prototype.recordWasFiltered): Deleted.
+ (WebInspector.TimelineRecordingContentView.prototype.matchTreeElementAgainstCustomFilters.checkTimeBounds): Deleted.
+ (WebInspector.TimelineRecordingContentView.prototype.matchTreeElementAgainstCustomFilters): Deleted.
+ Re-implemented in DataGrid.
+ (WebInspector.TimelineRecordingContentView.prototype._updateTimes): Deleted.
+ FIXME comment removed. Filtering occurs when TimelineView times are updated.
+ (WebInspector.TimelineRecordingContentView.prototype._timeRangeSelectionChanged): Deleted.
+
+ * UserInterface/Views/TimelineView.js:
+ (WebInspector.TimelineView):
+ (WebInspector.TimelineView.prototype.get navigationItems):
+ Used by TimelineRecordingContentView to add scope bar items to the
+ lower content browser's navigation bar.
+
+ (WebInspector.TimelineView.prototype.set startTime):
+ (WebInspector.TimelineView.prototype.set endTime):
+ (WebInspector.TimelineView.prototype.set currentTime):
+ Update grid filter when recording times change.
+ (WebInspector.TimelineView.prototype.get filterStartTime):
+ (WebInspector.TimelineView.prototype.get filterEndTime):
+ Let subclasses (RenderingFrameTimelineView) provide filter start/end times.
+ (WebInspector.TimelineView.prototype.setupDataGrid):
+ Register the grid used by the TimelineView subclass, allowing the base
+ class to hook into common event listeners and provide boilerplate functionality.
+
+ (WebInspector.TimelineView.prototype.updateFilter):
+ For data grid views, updates grid filters and sets new filter text.
+ (WebInspector.TimelineView.prototype.matchDataGridNodeAgainstCustomFilters):
+ (WebInspector.TimelineView.prototype.dataGridMatchNodeAgainstCustomFilters.checkTimeBounds):
+ (WebInspector.TimelineView.prototype.dataGridMatchNodeAgainstCustomFilters):
+ DataGrid filter delegate. Lets subclasses apply custom filters first,
+ then filters based on ruler selection if needed.
+
+ (WebInspector.TimelineView.prototype.filterDidChange):
+ Hook for subclasses to respond to filter changes.
+ (WebInspector.TimelineView.prototype._filterTimesDidChange.delayedWork):
+ (WebInspector.TimelineView.prototype._filterTimesDidChange):
+ Helper function for coalescing ruler selection updates into a single
+ filter update.
+
+ (WebInspector.TimelineView.prototype.matchTreeElementAgainstCustomFilters): Deleted.
+ (WebInspector.TimelineView.prototype.filterUpdated): Deleted.
+ No longer needed.
+
2016-04-25 Joseph Pecoraro <[email protected]>
Web Inspector: React.js JSXTransformer produces bogus error locations
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js (200066 => 200067)
--- trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js 2016-04-26 00:50:07 UTC (rev 200066)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js 2016-04-26 01:00:17 UTC (rev 200067)
@@ -53,6 +53,9 @@
this.resizers = [];
this._columnWidthsInitialized = false;
+ this._filterText = "";
+ this._filterDelegate = null;
+
this.element.className = "data-grid";
this.element.tabIndex = 0;
this.element.addEventListener("keydown", this._keyDown.bind(this), false);
@@ -281,6 +284,112 @@
this._scrollContainerElement.addEventListener("scroll", this._scrollListener);
}
+ set filterText(x)
+ {
+ if (this._filterText === x)
+ return;
+
+ this._filterText = x;
+ this.filterDidChange();
+ }
+
+ get filterDelegate() { return this._filterDelegate; }
+
+ set filterDelegate(delegate)
+ {
+ this._filterDelegate = delegate;
+ this.filterDidChange();
+ }
+
+ filterDidChange()
+ {
+ if (this._scheduledFilterUpdateIdentifier)
+ return;
+
+ this._scheduledFilterUpdateIdentifier = requestAnimationFrame(this._updateFilter.bind(this));
+ }
+
+ hasCustomFilters()
+ {
+ return this._hasFilterDelegate();
+ }
+
+ matchNodeAgainstCustomFilters(node)
+ {
+ if (!this._hasFilterDelegate())
+ return true;
+ return this._filterDelegate.dataGridMatchNodeAgainstCustomFilters(node);
+ }
+
+ _applyFiltersToNode(node)
+ {
+ if (!this._textFilterRegex && !this.hasCustomFilters()) {
+ // No filters, so make everything visible.
+ node.hidden = false;
+
+ // If the node was expanded during filtering, collapse it again.
+ if (node.expanded && node[WebInspector.DataGrid.WasExpandedDuringFilteringSymbol]) {
+ node[WebInspector.DataGrid.WasExpandedDuringFilteringSymbol] = false;
+ node.collapse();
+ }
+
+ return;
+ }
+
+ let filterableData = node.filterableData || [];
+ let flags = {expandNode: false};
+ let filterRegex = this._textFilterRegex;
+
+ function matchTextFilter()
+ {
+ if (!filterableData.length || !filterRegex)
+ return true;
+
+ if (filterableData.some((value) => filterRegex.test(value))) {
+ flags.expandNode = true;
+ return true;
+ }
+
+ return false;
+ }
+
+ function makeVisible()
+ {
+ // Make this element visible.
+ node.hidden = false;
+
+ // Make the ancestors visible and expand them.
+ let currentAncestor = node.parent;
+ while (currentAncestor && !currentAncestor.root) {
+ currentAncestor.hidden = false;
+
+ // Only expand if the built-in filters matched, not custom filters.
+ if (flags.expandNode && !currentAncestor.expanded) {
+ currentAncestor[WebInspector.DataGrid.WasExpandedDuringFilteringSymbol] = true;
+ currentAncestor.expand();
+ }
+
+ currentAncestor = currentAncestor.parent;
+ }
+ }
+
+ if (matchTextFilter() && this.matchNodeAgainstCustomFilters(node)) {
+ // Make the node visible since it matches.
+ makeVisible();
+
+ // If the node didn't match a built-in filter and was expanded earlier during filtering, collapse it again.
+ if (!flags.expandNode && node.expanded && node[WebInspector.DataGrid.WasExpandedDuringFilteringSymbol]) {
+ node[WebInspector.DataGrid.WasExpandedDuringFilteringSymbol] = false;
+ node.collapse();
+ }
+
+ return;
+ }
+
+ // Make the node invisible since it does not match.
+ node.hidden = true;
+ }
+
_updateSortedColumn(oldSortColumnIdentifier)
{
if (this._sortColumnIdentifierSetting)
@@ -301,6 +410,11 @@
this.dispatchEventToListeners(WebInspector.DataGrid.Event.SortChanged);
}
+ _hasFilterDelegate()
+ {
+ return this._filterDelegate && typeof this._filterDelegate.dataGridMatchNodeAgainstCustomFilters === "function";
+ }
+
_ondblclick(event)
{
if (this._editing || this._editingNode)
@@ -867,7 +981,7 @@
let rowHeight = this.rowHeight;
let updateOffsetThreshold = rowHeight * 5;
- let revealedRows = this._rows.filter((row) => row.revealed);
+ let revealedRows = this._rows.filter((row) => row.revealed && !row.hidden);
let scrollTop = this._scrollContainerElement.scrollTop;
let scrollHeight = this._scrollContainerElement.offsetHeight;
@@ -1569,13 +1683,51 @@
this._currentResizer = null;
}
+
+ _updateFilter()
+ {
+ if (this._scheduledFilterUpdateIdentifier) {
+ cancelAnimationFrame(this._scheduledFilterUpdateIdentifier);
+ this._scheduledFilterUpdateIdentifier = undefined;
+ }
+
+ if (!this._rows.length)
+ return;
+
+ this._textFilterRegex = simpleGlobStringToRegExp(this._filterText, "i");
+
+ // Don't populate if we don't have any active filters.
+ // We only need to populate when a filter needs to reveal.
+ let dontPopulate = !this._textFilterRegex && !this.hasCustomFilters();
+
+ let filterDidModifyNode = false;
+ let currentNode = this._rows[0];
+ while (currentNode && !currentNode.root) {
+ const currentNodeWasHidden = currentNode.hidden;
+ this._applyFiltersToNode(currentNode);
+ if (currentNodeWasHidden !== currentNode.hidden) {
+ this.dispatchEventToListeners(WebInspector.DataGrid.Event.NodeWasFiltered, {node: currentNode});
+ filterDidModifyNode = true;
+ }
+
+ currentNode = currentNode.traverseNextNode(false, null, dontPopulate);
+ }
+
+ if (!filterDidModifyNode)
+ return;
+
+ this._updateVisibleRows();
+ this.dispatchEventToListeners(WebInspector.DataGrid.Event.FilterDidChange);
+ }
};
WebInspector.DataGrid.Event = {
SortChanged: "datagrid-sort-changed",
SelectedNodeChanged: "datagrid-selected-node-changed",
ExpandedNode: "datagrid-expanded-node",
- CollapsedNode: "datagrid-collapsed-node"
+ CollapsedNode: "datagrid-collapsed-node",
+ FilterDidChange: "datagrid-filter-did-change",
+ NodeWasFiltered: "datagrid-node-was-filtered"
};
WebInspector.DataGrid.ResizeMethod = {
@@ -1592,6 +1744,7 @@
WebInspector.DataGrid.PreviousColumnOrdinalSymbol = Symbol("previous-column-ordinal");
WebInspector.DataGrid.NextColumnOrdinalSymbol = Symbol("next-column-ordinal");
+WebInspector.DataGrid.WasExpandedDuringFilteringSymbol = Symbol("was-expanded-during-filtering");
WebInspector.DataGrid.ColumnResizePadding = 10;
WebInspector.DataGrid.CenterResizerOverBorderAdjustment = 3;
@@ -1726,6 +1879,30 @@
this.needsRefresh();
}
+ get filterableData()
+ {
+ if (this._cachedFilterableData)
+ return this._cachedFilterableData;
+
+ this._cachedFilterableData = [];
+
+ for (let column of this.dataGrid.columns.values()) {
+ let value = this.filterableDataForColumn(column.columnIdentifier);
+ if (!value)
+ continue;
+
+ if (!(value instanceof Array))
+ value = [value];
+
+ if (!value.length)
+ continue;
+
+ this._cachedFilterableData = this._cachedFilterableData.concat(value);
+ }
+
+ return this._cachedFilterableData;
+ }
+
get revealed()
{
if ("_revealed" in this)
@@ -1856,6 +2033,7 @@
this._scheduledRefreshIdentifier = undefined;
}
+ this._cachedFilterableData = null;
this._needsRefresh = false;
this._element.removeChildren();
@@ -2254,6 +2432,14 @@
// Subclasses may override
return null;
}
+
+ // Protected
+
+ filterableDataForColumn(columnIdentifier)
+ {
+ let value = this.data[columnIdentifier];
+ return typeof value === "string" ? value : null;
+ }
};
// Used to create a new table row when entering new data by editing cells.
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/LayoutTimelineDataGridNode.js (200066 => 200067)
--- trunk/Source/WebInspectorUI/UserInterface/Views/LayoutTimelineDataGridNode.js 2016-04-26 00:50:07 UTC (rev 200066)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/LayoutTimelineDataGridNode.js 2016-04-26 01:00:17 UTC (rev 200067)
@@ -44,6 +44,7 @@
{
if (!this._cachedData) {
this._cachedData = {
+ type: this._record.eventType,
name: this.displayName(),
width: this._record.width,
height: this._record.height,
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/LayoutTimelineView.js (200066 => 200067)
--- trunk/Source/WebInspectorUI/UserInterface/Views/LayoutTimelineView.js 2016-04-26 00:50:07 UTC (rev 200066)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/LayoutTimelineView.js 2016-04-26 01:00:17 UTC (rev 200067)
@@ -31,7 +31,7 @@
console.assert(timeline.type === WebInspector.TimelineRecord.Type.Layout, timeline);
- let columns = {name: {}, location: {}, width: {}, height: {}, startTime: {}, totalTime: {}};
+ let columns = {type: {}, name: {}, location: {}, width: {}, height: {}, startTime: {}, totalTime: {}};
columns.name.title = WebInspector.UIString("Type");
columns.name.width = "15%";
@@ -42,11 +42,13 @@
typeToLabelMap.set(value, WebInspector.LayoutTimelineRecord.displayNameForEventType(value));
}
- columns.name.scopeBar = WebInspector.TimelineDataGrid.createColumnScopeBar("layout", typeToLabelMap);
+ columns.type.scopeBar = WebInspector.TimelineDataGrid.createColumnScopeBar("layout", typeToLabelMap);
+ columns.type.hidden = true;
+
columns.name.disclosure = true;
columns.name.icon = true;
- this._scopeBar = columns.name.scopeBar;
+ this._scopeBar = columns.type.scopeBar;
columns.location.title = WebInspector.UIString("Initiator");
columns.location.width = "25%";
@@ -69,9 +71,10 @@
columns[column].sortable = true;
this._dataGrid = new WebInspector.LayoutTimelineDataGrid(columns);
- this._dataGrid.addEventListener(WebInspector.TimelineDataGrid.Event.FiltersDidChange, this._dataGridFiltersDidChange, this);
- this._dataGrid.addEventListener(WebInspector.DataGrid.Event.SelectedNodeChanged, this._dataGridNodeSelected, this);
+ this._dataGrid.addEventListener(WebInspector.DataGrid.Event.SelectedNodeChanged, this._dataGridSelectedNodeChanged, this);
+ this.setupDataGrid(this._dataGrid);
+
this._dataGrid.sortColumnIdentifierSetting = new WebInspector.Setting("layout-timeline-view-sort", "startTime");
this._dataGrid.sortOrderSetting = new WebInspector.Setting("layout-timeline-view-sort-order", WebInspector.DataGrid.SortOrder.Ascending);
@@ -141,18 +144,6 @@
this._dataGrid.closed();
}
- filterDidChange()
- {
- super.filterDidChange();
-
- this._updateHighlight();
- }
-
- matchTreeElementAgainstCustomFilters(treeElement)
- {
- return this._dataGrid.treeElementMatchesActiveScopeFilters(treeElement);
- }
-
reset()
{
super.reset();
@@ -174,9 +165,9 @@
dataGridNode.revealAndSelect();
}
- treeElementDeselected(treeElement)
+ filterDidChange()
{
- super.treeElementDeselected(treeElement);
+ super.filterDidChange();
this._updateHighlight();
}
@@ -246,16 +237,6 @@
this.needsLayout();
}
- _dataGridFiltersDidChange(event)
- {
- // FIXME: <https://webkit.org/b/154924> Web Inspector: hook up grid row filtering in the new Timelines UI
- }
-
- _dataGridNodeSelected(event)
- {
- this.dispatchEventToListeners(WebInspector.ContentView.Event.SelectionPathComponentsDidChange);
- }
-
_updateHighlight()
{
var record = this._hoveredOrSelectedRecord();
@@ -327,4 +308,9 @@
this._hoveredDataGridNode = null;
this._updateHighlight();
}
+
+ _dataGridSelectedNodeChanged(event)
+ {
+ this._updateHighlight();
+ }
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTimelineView.js (200066 => 200067)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTimelineView.js 2016-04-26 00:50:07 UTC (rev 200066)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTimelineView.js 2016-04-26 01:00:17 UTC (rev 200067)
@@ -88,12 +88,12 @@
columns[column].sortable = true;
this._dataGrid = new WebInspector.TimelineDataGrid(columns);
- this._dataGrid.addEventListener(WebInspector.TimelineDataGrid.Event.FiltersDidChange, this._dataGridFiltersDidChange, this);
- this._dataGrid.addEventListener(WebInspector.DataGrid.Event.SelectedNodeChanged, this._dataGridNodeSelected, this);
this._dataGrid.sortDelegate = this;
this._dataGrid.sortColumnIdentifierSetting = new WebInspector.Setting("network-timeline-view-sort", "requestSent");
this._dataGrid.sortOrderSetting = new WebInspector.Setting("network-timeline-view-sort-order", WebInspector.DataGrid.SortOrder.Ascending);
+ this.setupDataGrid(this._dataGrid);
+
this.element.classList.add("network");
this.addSubview(this._dataGrid);
@@ -139,11 +139,6 @@
this._dataGrid.closed();
}
- matchTreeElementAgainstCustomFilters(treeElement)
- {
- return this._dataGrid.treeElementMatchesActiveScopeFilters(treeElement);
- }
-
reset()
{
super.reset();
@@ -235,14 +230,4 @@
this.needsLayout();
}
-
- _dataGridFiltersDidChange(event)
- {
- // FIXME: <https://webkit.org/b/154924> Web Inspector: hook up grid row filtering in the new Timelines UI
- }
-
- _dataGridNodeSelected(event)
- {
- this.dispatchEventToListeners(WebInspector.ContentView.Event.SelectionPathComponentsDidChange);
- }
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/OverviewTimelineView.js (200066 => 200067)
--- trunk/Source/WebInspectorUI/UserInterface/Views/OverviewTimelineView.js 2016-04-26 00:50:07 UTC (rev 200066)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/OverviewTimelineView.js 2016-04-26 01:00:17 UTC (rev 200067)
@@ -45,8 +45,9 @@
columns.graph.headerView = this._timelineRuler;
this._dataGrid = new WebInspector.DataGrid(columns);
- this._dataGrid.addEventListener(WebInspector.DataGrid.Event.SelectedNodeChanged, this._dataGridNodeSelected, this);
+ this.setupDataGrid(this._dataGrid);
+
this._currentTimeMarker = new WebInspector.TimelineMarker(0, WebInspector.TimelineMarker.Type.CurrentTime);
this._timelineRuler.addMarker(this._currentTimeMarker);
@@ -294,11 +295,6 @@
this._timelineRuler.addMarker(event.data.marker);
}
- _dataGridNodeSelected(event)
- {
- this.dispatchEventToListeners(WebInspector.ContentView.Event.SelectionPathComponentsDidChange);
- }
-
_recordingReset(event)
{
this._timelineRuler.clearMarkers();
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/RenderingFrameTimelineView.js (200066 => 200067)
--- trunk/Source/WebInspectorUI/UserInterface/Views/RenderingFrameTimelineView.js 2016-04-26 00:50:07 UTC (rev 200066)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/RenderingFrameTimelineView.js 2016-04-26 01:00:17 UTC (rev 200067)
@@ -77,10 +77,11 @@
columns[column].sortable = true;
this._dataGrid = new WebInspector.TimelineDataGrid(columns);
- this._dataGrid.addEventListener(WebInspector.DataGrid.Event.SelectedNodeChanged, this._dataGridNodeSelected, this);
this._dataGrid.sortColumnIdentifierSetting = new WebInspector.Setting("rendering-frame-timeline-view-sort", "startTime");
this._dataGrid.sortOrderSetting = new WebInspector.Setting("rendering-frame-timeline-view-sort-order", WebInspector.DataGrid.SortOrder.Ascending);
+ this.setupDataGrid(this._dataGrid);
+
this.element.classList.add("rendering-frame");
this.addSubview(this._dataGrid);
@@ -151,22 +152,24 @@
return pathComponents;
}
- matchTreeElementAgainstCustomFilters(treeElement)
+ get filterStartTime()
{
- console.assert(this._scopeBar.selectedItems.length === 1);
- var selectedScopeBarItem = this._scopeBar.selectedItems[0];
- if (!selectedScopeBarItem || selectedScopeBarItem.id === WebInspector.RenderingFrameTimelineView.DurationFilter.All)
- return true;
+ let records = this.representedObject.records;
+ let startIndex = this.startTime;
+ if (startIndex >= records.length)
+ return Infinity;
- while (treeElement && !(treeElement.record instanceof WebInspector.RenderingFrameTimelineRecord))
- treeElement = treeElement.parent;
+ return records[startIndex].startTime;
+ }
- console.assert(treeElement, "Cannot apply duration filter: no RenderingFrameTimelineRecord found.");
- if (!treeElement)
- return false;
+ get filterEndTime()
+ {
+ let records = this.representedObject.records;
+ let endIndex = this.endTime - 1;
+ if (endIndex >= records.length)
+ return Infinity;
- var minimumDuration = selectedScopeBarItem.id === WebInspector.RenderingFrameTimelineView.DurationFilter.OverOneMillisecond ? 0.001 : 0.015;
- return treeElement.record.duration > minimumDuration;
+ return records[endIndex].endTime;
}
reset()
@@ -195,6 +198,28 @@
return null;
}
+ matchDataGridNodeAgainstCustomFilters(node)
+ {
+ if (!super.matchDataGridNodeAgainstCustomFilters(node))
+ return false;
+
+ console.assert(node instanceof WebInspector.TimelineDataGridNode);
+ console.assert(this._scopeBar.selectedItems.length === 1);
+ let selectedScopeBarItem = this._scopeBar.selectedItems[0];
+ if (!selectedScopeBarItem || selectedScopeBarItem.id === WebInspector.RenderingFrameTimelineView.DurationFilter.All)
+ return true;
+
+ while (node && !(node.record instanceof WebInspector.RenderingFrameTimelineRecord))
+ node = node.parent;
+
+ console.assert(node, "Cannot apply duration filter: no RenderingFrameTimelineRecord found.");
+ if (!node)
+ return false;
+
+ let minimumDuration = selectedScopeBarItem.id === WebInspector.RenderingFrameTimelineView.DurationFilter.OverOneMillisecond ? 0.001 : 0.015;
+ return node.record.duration > minimumDuration;
+ }
+
layout()
{
this._processPendingRecords();
@@ -264,15 +289,10 @@
this.needsLayout();
}
- _dataGridNodeSelected(event)
+ _scopeBarSelectionDidChange()
{
- this.dispatchEventToListeners(WebInspector.ContentView.Event.SelectionPathComponentsDidChange);
+ this.filterDidChange();
}
-
- _scopeBarSelectionDidChange(event)
- {
- // FIXME: <https://webkit.org/b/154924> Web Inspector: hook up grid row filtering in the new Timelines UI
- }
};
WebInspector.RenderingFrameTimelineView.DurationFilter = {
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimelineDataGridNode.js (200066 => 200067)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimelineDataGridNode.js 2016-04-26 00:50:07 UTC (rev 200066)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimelineDataGridNode.js 2016-04-26 01:00:17 UTC (rev 200067)
@@ -146,6 +146,15 @@
return [WebInspector.ResourceTreeElement.ResourceIconStyleClassName, this.resource.type];
}
+ // Protected
+
+ filterableDataForColumn(columnIdentifier)
+ {
+ if (columnIdentifier === "name")
+ return this._resource.url;
+ return super.filterableDataForColumn(columnIdentifier);
+ }
+
// Private
_createNameCellDocumentFragment()
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ScriptClusterTimelineView.js (200066 => 200067)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ScriptClusterTimelineView.js 2016-04-26 00:50:07 UTC (rev 200066)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ScriptClusterTimelineView.js 2016-04-26 01:00:17 UTC (rev 200067)
@@ -71,8 +71,9 @@
set currentTime(x) { this._contentViewContainer.currentContentView.currentTime = x; }
get navigationSidebarTreeOutline() { return this._contentViewContainer.currentContentView.navigationSidebarTreeOutline; }
reset() { return this._contentViewContainer.currentContentView.reset(); }
+ updateFilter(filters) { return this._contentViewContainer.currentContentView.updateFilter(filters); }
filterDidChange() { return this._contentViewContainer.currentContentView.filterDidChange(); }
- matchTreeElementAgainstCustomFilters(treeElement) { return this._contentViewContainer.currentContentView.matchTreeElementAgainstCustomFilters(treeElement); }
+ matchDataGridNodeAgainstCustomFilters(node) { return this._contentViewContainer.currentContentView.matchDataGridNodeAgainstCustomFilters(node); }
// Public
@@ -196,8 +197,6 @@
currentContentView.startTime = previousContentView.startTime;
currentContentView.endTime = previousContentView.endTime;
currentContentView.currentTime = previousContentView.currentTime;
-
- // FIXME: <https://webkit.org/b/154924> Web Inspector: hook up grid row filtering in the new Timelines UI
}
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ScriptDetailsTimelineView.js (200066 => 200067)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ScriptDetailsTimelineView.js 2016-04-26 00:50:07 UTC (rev 200066)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ScriptDetailsTimelineView.js 2016-04-26 01:00:17 UTC (rev 200067)
@@ -72,12 +72,12 @@
columns[column].sortable = true;
this._dataGrid = new WebInspector.ScriptTimelineDataGrid(columns);
- this._dataGrid.addEventListener(WebInspector.TimelineDataGrid.Event.FiltersDidChange, this._dataGridFiltersDidChange, this);
- this._dataGrid.addEventListener(WebInspector.DataGrid.Event.SelectedNodeChanged, this._dataGridNodeSelected, this);
this._dataGrid.sortDelegate = this;
this._dataGrid.sortColumnIdentifierSetting = new WebInspector.Setting("script-timeline-view-sort", "startTime");
this._dataGrid.sortOrderSetting = new WebInspector.Setting("script-timeline-view-sort-order", WebInspector.DataGrid.SortOrder.Ascending);
+ this.setupDataGrid(this._dataGrid);
+
this.element.classList.add("script");
this.addSubview(this._dataGrid);
@@ -236,14 +236,4 @@
{
this.needsLayout();
}
-
- _dataGridFiltersDidChange(event)
- {
- // FIXME: <https://webkit.org/b/154924> Web Inspector: hook up grid row filtering in the new Timelines UI
- }
-
- _dataGridNodeSelected(event)
- {
- this.dispatchEventToListeners(WebInspector.ContentView.Event.SelectionPathComponentsDidChange);
- }
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ScriptTimelineDataGridNode.js (200066 => 200067)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ScriptTimelineDataGridNode.js 2016-04-26 00:50:07 UTC (rev 200066)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ScriptTimelineDataGridNode.js 2016-04-26 01:00:17 UTC (rev 200067)
@@ -156,6 +156,16 @@
return super.createCellContent(columnIdentifier, cell);
}
+ // Protected
+
+ filterableDataForColumn(columnIdentifier)
+ {
+ if (columnIdentifier === "name")
+ return [this.displayName(), this.subtitle];
+
+ return super.filterableDataForColumn(columnIdentifier);
+ }
+
// Private
_createNameCellDocumentFragment(cellElement)
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineDataGrid.js (200066 => 200067)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineDataGrid.js 2016-04-26 00:50:07 UTC (rev 200066)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineDataGrid.js 2016-04-26 01:00:17 UTC (rev 200067)
@@ -25,17 +25,17 @@
WebInspector.TimelineDataGrid = class TimelineDataGrid extends WebInspector.DataGrid
{
- constructor(columns, treeOutline, delegate, editCallback, deleteCallback)
+ constructor(columns, treeOutline, synchronizerDelegate, editCallback, deleteCallback)
{
super(columns, editCallback, deleteCallback);
if (treeOutline)
- this._treeOutlineDataGridSynchronizer = new WebInspector.TreeOutlineDataGridSynchronizer(treeOutline, this, delegate);
+ this._treeOutlineDataGridSynchronizer = new WebInspector.TreeOutlineDataGridSynchronizer(treeOutline, this, synchronizerDelegate);
this.element.classList.add("timeline");
- this._filterableColumns = [];
this._sortDelegate = null;
+ this._scopeBarColumns = [];
// Check if any of the cells can be filtered.
for (var [identifier, column] of this.columns) {
@@ -44,12 +44,12 @@
if (!scopeBar)
continue;
- this._filterableColumns.push(identifier);
+ this._scopeBarColumns.push(identifier);
scopeBar.columnIdentifier = identifier;
scopeBar.addEventListener(WebInspector.ScopeBar.Event.SelectionChanged, this._scopeBarSelectedItemsDidChange, this);
}
- if (this._filterableColumns.length > 1) {
+ if (this._scopeBarColumns.length > 1) {
console.error("Creating a TimelineDataGrid with more than one filterable column is not yet supported.");
return;
}
@@ -149,31 +149,6 @@
return null;
}
- treeElementMatchesActiveScopeFilters(treeElement)
- {
- if (!this._treeOutlineDataGridSynchronizer)
- return false;
-
- var dataGridNode = this._treeOutlineDataGridSynchronizer.dataGridNodeForTreeElement(treeElement);
- console.assert(dataGridNode);
-
- for (var identifier of this._filterableColumns) {
- var scopeBar = this.columns.get(identifier).scopeBar;
- if (!scopeBar || scopeBar.defaultItem.selected)
- continue;
-
- var value = dataGridNode.data[identifier];
- var matchesFilter = scopeBar.selectedItems.some(function(scopeBarItem) {
- return scopeBarItem.value === value;
- });
-
- if (!matchesFilter)
- return false;
- }
-
- return true;
- }
-
addRowInSortOrder(treeElement, dataGridNode, parentTreeElementOrDataGridNode)
{
let parentDataGridNode;
@@ -235,6 +210,29 @@
this._scheduledDataGridNodeRefreshIdentifier = requestAnimationFrame(this._refreshDirtyDataGridNodes.bind(this));
}
+ hasCustomFilters()
+ {
+ return true;
+ }
+
+ matchNodeAgainstCustomFilters(node)
+ {
+ if (!super.matchNodeAgainstCustomFilters(node))
+ return false;
+
+ for (let identifier of this._scopeBarColumns) {
+ let scopeBar = this.columns.get(identifier).scopeBar;
+ if (!scopeBar || scopeBar.defaultItem.selected)
+ continue;
+
+ let value = node.data[identifier];
+ if (!scopeBar.selectedItems.some((scopeBarItem) => scopeBarItem.value === value))
+ return false;
+ }
+
+ return true;
+ }
+
// Private
_refreshDirtyDataGridNodes()
@@ -420,23 +418,9 @@
return (value1 < value2 ? -1 : (value1 > value2 ? 1 : 0)) * sortDirection;
}
- _updateScopeBarForcedVisibility()
- {
- for (var identifier of this._filterableColumns) {
- var scopeBar = this.columns.get(identifier).scopeBar;
- if (scopeBar) {
- this.element.classList.toggle(WebInspector.TimelineDataGrid.HasNonDefaultFilterStyleClassName, scopeBar.hasNonDefaultItemSelected());
- break;
- }
- }
- }
-
_scopeBarSelectedItemsDidChange(event)
{
- this._updateScopeBarForcedVisibility();
-
- var columnIdentifier = event.target.columnIdentifier;
- this.dispatchEventToListeners(WebInspector.TimelineDataGrid.Event.FiltersDidChange, {columnIdentifier});
+ this.filterDidChange();
}
_dataGridSelectedNodeChanged(event)
@@ -564,11 +548,8 @@
}
};
+WebInspector.TimelineDataGrid.WasExpandedDuringFilteringSymbol = Symbol("was-expanded-during-filtering");
+
WebInspector.TimelineDataGrid.HasNonDefaultFilterStyleClassName = "has-non-default-filter";
WebInspector.TimelineDataGrid.DelayedPopoverShowTimeout = 250;
WebInspector.TimelineDataGrid.DelayedPopoverHideContentClearTimeout = 500;
-
-WebInspector.TimelineDataGrid.Event = {
- FiltersDidChange: "timelinedatagrid-filters-did-change"
-};
-
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineDataGridNode.js (200066 => 200067)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineDataGridNode.js 2016-04-26 00:50:07 UTC (rev 200066)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineDataGridNode.js 2016-04-26 01:00:17 UTC (rev 200067)
@@ -364,4 +364,16 @@
return true;
}
+
+ filterableDataForColumn(columnIdentifier)
+ {
+ let value = this.data[columnIdentifier];
+ if (value instanceof WebInspector.SourceCodeLocation)
+ return value.displayLocationString();
+
+ if (value instanceof WebInspector.CallFrame)
+ return [value.functionName, value.sourceCodeLocation.displayLocationString()];
+
+ return super.filterableDataForColumn(columnIdentifier);
+ }
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordingContentView.js (200066 => 200067)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordingContentView.js 2016-04-26 00:50:07 UTC (rev 200066)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordingContentView.js 2016-04-26 01:00:17 UTC (rev 200067)
@@ -53,6 +53,7 @@
this._filterBarNavigationItem = new WebInspector.FilterBarNavigationItem;
this._filterBarNavigationItem.filterBar.placeholder = WebInspector.UIString("Filter Records");
+ this._filterBarNavigationItem.filterBar.addEventListener(WebInspector.FilterBar.Event.FilterDidChange, this._filterDidChange, this);
this._timelineContentBrowser.navigationBar.addNavigationItem(this._filterBarNavigationItem);
this.addSubview(this._timelineContentBrowser);
@@ -85,6 +86,8 @@
WebInspector.ContentView.addEventListener(WebInspector.ContentView.Event.SelectionPathComponentsDidChange, this._contentViewSelectionPathComponentDidChange, this);
WebInspector.ContentView.addEventListener(WebInspector.ContentView.Event.SupplementalRepresentedObjectsDidChange, this._contentViewSupplementalRepresentedObjectsDidChange, this);
+ WebInspector.TimelineView.addEventListener(WebInspector.TimelineView.Event.RecordWasFiltered, this._recordWasFiltered, this);
+
for (let instrument of this._recording.instruments)
this._instrumentAdded(instrument);
@@ -215,94 +218,6 @@
this._timelineContentBrowser.goForward();
}
- filterDidChange()
- {
- if (!this.currentTimelineView)
- return;
-
- this.currentTimelineView.filterDidChange();
- }
-
- recordWasFiltered(record, filtered)
- {
- if (!this.currentTimelineView)
- return;
-
- this._timelineOverview.recordWasFiltered(this.currentTimelineView.representedObject, record, filtered);
- }
-
- matchTreeElementAgainstCustomFilters(treeElement)
- {
- if (this.currentTimelineView && !this.currentTimelineView.matchTreeElementAgainstCustomFilters(treeElement))
- return false;
-
- let startTime = this._timelineOverview.selectionStartTime;
- let endTime = startTime + this._timelineOverview.selectionDuration;
- let currentTime = this._currentTime || this._recording.startTime;
-
- if (this._timelineOverview.viewMode === WebInspector.TimelineOverview.ViewMode.RenderingFrames) {
- console.assert(this._renderingFrameTimeline);
-
- if (this._renderingFrameTimeline && this._renderingFrameTimeline.records.length) {
- let records = this._renderingFrameTimeline.records;
- let startIndex = this._timelineOverview.timelineRuler.snapInterval ? startTime : Math.floor(startTime);
- if (startIndex >= records.length)
- return false;
-
- let endIndex = this._timelineOverview.timelineRuler.snapInterval ? endTime - 1: Math.floor(endTime);
- endIndex = Math.min(endIndex, records.length - 1);
- console.assert(startIndex <= endIndex, startIndex);
-
- startTime = records[startIndex].startTime;
- endTime = records[endIndex].endTime;
- }
- }
-
- function checkTimeBounds(itemStartTime, itemEndTime)
- {
- itemStartTime = itemStartTime || currentTime;
- itemEndTime = itemEndTime || currentTime;
-
- return startTime <= itemEndTime && itemStartTime <= endTime;
- }
-
- if (treeElement instanceof WebInspector.ResourceTreeElement) {
- var resource = treeElement.resource;
- return checkTimeBounds(resource.requestSentTimestamp, resource.finishedOrFailedTimestamp);
- }
-
- if (treeElement instanceof WebInspector.SourceCodeTimelineTreeElement) {
- var sourceCodeTimeline = treeElement.sourceCodeTimeline;
-
- // Do a quick check of the timeline bounds before we check each record.
- if (!checkTimeBounds(sourceCodeTimeline.startTime, sourceCodeTimeline.endTime))
- return false;
-
- for (var record of sourceCodeTimeline.records) {
- if (checkTimeBounds(record.startTime, record.endTime))
- return true;
- }
-
- return false;
- }
-
- if (treeElement instanceof WebInspector.ProfileNodeTreeElement) {
- var profileNode = treeElement.profileNode;
- if (checkTimeBounds(profileNode.startTime, profileNode.endTime))
- return true;
-
- return false;
- }
-
- if (treeElement instanceof WebInspector.TimelineRecordTreeElement) {
- var record = treeElement.record;
- return checkTimeBounds(record.startTime, record.endTime);
- }
-
- console.error("Unknown TreeElement, can't filter by time.");
- return true;
- }
-
// ContentBrowser delegate
contentBrowserTreeElementForRepresentedObject(contentBrowser, representedObject)
@@ -470,9 +385,6 @@
if (this._timelineOverview.timelineRuler.entireRangeSelected)
this._updateTimelineViewSelection(this._overviewTimelineView);
- // Filter records on new recording times.
- // FIXME: <https://webkit.org/b/154924> Web Inspector: hook up grid row filtering in the new Timelines UI
-
// Force a layout now since we are already in an animation frame and don't need to delay it until the next.
this._timelineOverview.updateLayoutIfNeeded();
if (this.currentTimelineView)
@@ -699,18 +611,6 @@
this._selectedTimeRangePathComponent = selectedPathComponent;
this.dispatchEventToListeners(WebInspector.ContentView.Event.SelectionPathComponentsDidChange);
}
-
- // Delay until the next frame to stay in sync with the current timeline view's time-based layout changes.
- requestAnimationFrame(function() {
- var selectedTreeElement = this.currentTimelineView && this.currentTimelineView.navigationSidebarTreeOutline ? this.currentTimelineView.navigationSidebarTreeOutline.selectedTreeElement : null;
- var selectionWasHidden = selectedTreeElement && selectedTreeElement.hidden;
-
- // Filter records on new timeline selection.
- // FIXME: <https://webkit.org/b/154924> Web Inspector: hook up grid row filtering in the new Timelines UI
-
- if (selectedTreeElement && selectedTreeElement.hidden !== selectionWasHidden)
- this.dispatchEventToListeners(WebInspector.ContentView.Event.SelectionPathComponentsDidChange);
- }.bind(this));
}
_recordSelected(event)
@@ -796,4 +696,22 @@
this._updateTimelineOverviewHeight();
}
+
+ _filterDidChange()
+ {
+ if (!this.currentTimelineView)
+ return;
+
+ this.currentTimelineView.updateFilter(this._filterBarNavigationItem.filterBar.filters);
+ }
+
+ _recordWasFiltered(event)
+ {
+ if (event.target !== this.currentTimelineView)
+ return;
+
+ let record = event.data.record;
+ let filtered = event.data.filtered;
+ this._timelineOverview.recordWasFiltered(this.currentTimelineView.representedObject, record, filtered);
+ }
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TimelineView.js (200066 => 200067)
--- trunk/Source/WebInspectorUI/UserInterface/Views/TimelineView.js 2016-04-26 00:50:07 UTC (rev 200066)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TimelineView.js 2016-04-26 01:00:17 UTC (rev 200067)
@@ -43,6 +43,11 @@
// Public
+ get navigationItems()
+ {
+ return this._scopeBar ? [this._scopeBar] : [];
+ }
+
get navigationSidebarTreeOutlineScopeBar()
{
return this._scopeBar;
@@ -85,6 +90,7 @@
this._startTime = x;
+ this._filterTimesDidChange();
this.needsLayout();
}
@@ -102,6 +108,7 @@
this._endTime = x;
+ this._filterTimesDidChange();
this.needsLayout();
}
@@ -128,20 +135,47 @@
return this._startTime - wiggleTime <= currentTime && currentTime <= this._endTime + wiggleTime;
}
- if (checkIfLayoutIsNeeded.call(this, oldCurrentTime) || checkIfLayoutIsNeeded.call(this, this._currentTime))
+ if (checkIfLayoutIsNeeded.call(this, oldCurrentTime) || checkIfLayoutIsNeeded.call(this, this._currentTime)) {
+ this._filterTimesDidChange();
this.needsLayout();
+ }
}
- reset()
+ get filterStartTime()
{
// Implemented by sub-classes if needed.
+ return this.startTime;
}
- filterDidChange()
+ get filterEndTime()
{
// Implemented by sub-classes if needed.
+ return this.endTime;
}
+ setupDataGrid(dataGrid)
+ {
+ console.assert(!this._timelineDataGrid);
+
+ 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();
+ });
+ }
+
selectRecord(record)
{
if (!this._timelineDataGrid)
@@ -166,17 +200,25 @@
dataGridNode.revealAndSelect();
}
- matchTreeElementAgainstCustomFilters(treeElement)
+ reset()
{
// Implemented by sub-classes if needed.
- return true;
}
- filterUpdated()
+ updateFilter(filters)
{
- this.dispatchEventToListeners(WebInspector.ContentView.Event.SelectionPathComponentsDidChange);
+ if (!this._timelineDataGrid)
+ return;
+
+ this._timelineDataGrid.filterText = filters ? filters.text : "";
}
+ matchDataGridNodeAgainstCustomFilters(node)
+ {
+ // Implemented by sub-classes if needed.
+ return true;
+ }
+
needsLayout()
{
// FIXME: needsLayout can be removed once <https://webkit.org/b/150741> is fixed.
@@ -186,10 +228,92 @@
super.needsLayout();
}
+ // DataGrid filter delegate
+
+ dataGridMatchNodeAgainstCustomFilters(node)
+ {
+ console.assert(node);
+ if (!this.matchDataGridNodeAgainstCustomFilters(node))
+ return false;
+
+ let startTime = this.filterStartTime;
+ let endTime = this.filterEndTime;
+ let currentTime = this.currentTime;
+
+ function checkTimeBounds(itemStartTime, itemEndTime)
+ {
+ itemStartTime = itemStartTime || currentTime;
+ itemEndTime = itemEndTime || currentTime;
+
+ return startTime <= itemEndTime && itemStartTime <= endTime;
+ }
+
+ if (node instanceof WebInspector.ResourceTimelineDataGridNode) {
+ let resource = node.resource;
+ return checkTimeBounds(resource.requestSentTimestamp, resource.finishedOrFailedTimestamp);
+ }
+
+ if (node instanceof WebInspector.SourceCodeTimelineTimelineDataGridNode) {
+ let sourceCodeTimeline = node.sourceCodeTimeline;
+
+ // Do a quick check of the timeline bounds before we check each record.
+ if (!checkTimeBounds(sourceCodeTimeline.startTime, sourceCodeTimeline.endTime))
+ return false;
+
+ for (let record of sourceCodeTimeline.records) {
+ if (checkTimeBounds(record.startTime, record.endTime))
+ return true;
+ }
+
+ return false;
+ }
+
+ if (node instanceof WebInspector.ProfileNodeDataGridNode) {
+ let profileNode = node.profileNode;
+ if (checkTimeBounds(profileNode.startTime, profileNode.endTime))
+ return true;
+
+ return false;
+ }
+
+ if (node instanceof WebInspector.TimelineDataGridNode) {
+ let record = node.record;
+ return checkTimeBounds(record.startTime, record.endTime);
+ }
+
+ console.error("Unknown DataGridNode, can't filter by time.");
+ return true;
+ }
+
// Protected
userSelectedRecordFromOverview(timelineRecord)
{
// Implemented by sub-classes if needed.
}
+
+ filterDidChange()
+ {
+ // Implemented by sub-classes if needed.
+ }
+
+ // Private
+
+ _filterTimesDidChange()
+ {
+ if (!this._timelineDataGrid || this._updateFilterTimeout)
+ return;
+
+ function delayedWork()
+ {
+ this._updateFilterTimeout = undefined;
+ this._timelineDataGrid.filterDidChange();
+ }
+
+ this._updateFilterTimeout = setTimeout(delayedWork.bind(this), 0);
+ }
};
+
+WebInspector.TimelineView.Event = {
+ RecordWasFiltered: "record-was-filtered"
+};