Changeset 162560 in webkit


Ignore:
Timestamp:
Jan 22, 2014, 2:57:11 PM (11 years ago)
Author:
timothy@apple.com
Message:

Support collapsing call site records into the resource timeline.

Also fix some filtering and graph issues.

https://bugs.webkit.org/show_bug.cgi?id=127440

Reviewed by Joseph Pecoraro.

  • UserInterface/NavigationSidebarPanel.js:

(WebInspector.NavigationSidebarPanel.prototype.updateFilter):
(WebInspector.NavigationSidebarPanel.prototype.applyFiltersToTreeElement.matchTextFilter):
(WebInspector.NavigationSidebarPanel.prototype.applyFiltersToTreeElement.makeVisible):
(WebInspector.NavigationSidebarPanel.prototype.applyFiltersToTreeElement):
(WebInspector.NavigationSidebarPanel.prototype._updateFilter):
Tweak how filtering happens so custom filters never expand to reveal and auto expanded
tree elements will auto-collapse again later even with custom filters.

  • UserInterface/OverviewTimelineView.css:

(.timeline-view.overview > .data-grid tr.parent:not(.expanded) td.graph-column .timeline-record-bar:not(.timeline-record-type-network) > .segment):
(.timeline-view.overview > .data-grid tr.parent:not(.expanded).selected td.graph-column .timeline-record-bar:not(.timeline-record-type-network) > .segment):
(.timeline-view.overview > .data-grid:focus tr.parent:not(.expanded).selected td.graph-column .timeline-record-bar:not(.timeline-record-type-network) > .segment):
Add a shadow to provide some negative space between juxtaposed records. Only needed when not expanded and not netwrok records.

  • UserInterface/OverviewTimelineView.js:

(WebInspector.OverviewTimelineView.prototype.updateLayout):
(WebInspector.OverviewTimelineView.prototype._addResourceToTreeIfNeeded):
Update the filter when current time changes and only auto expand the main resource.

  • UserInterface/ResourceTimelineDataGridNode.js:

(WebInspector.ResourceTimelineDataGridNode):
(WebInspector.ResourceTimelineDataGridNode.prototype._timelineRecordUpdated):
Don't schedule a refresh of the graph if the record isn't visible.

  • UserInterface/SourceCodeTimelineTimelineDataGridNode.js:

(WebInspector.SourceCodeTimelineTimelineDataGridNode):
(WebInspector.SourceCodeTimelineTimelineDataGridNode.prototype._timelineRecordAdded):
Don't schedule a refresh of the graph if the record isn't visible.

  • UserInterface/TimelineContentView.js:

(WebInspector.TimelineContentView.prototype._timeRangeSelectionChanged):
Remove the boolean for updateFilter.

  • UserInterface/TimelineDataGrid.js:

(WebInspector.TimelineDataGrid.prototype._refreshDirtyDataGridNodes):
(WebInspector.TimelineDataGrid.prototype._sort):
Keep the hidden state in-sync between node and element.

  • UserInterface/TimelineDataGridNode.js:

(WebInspector.TimelineDataGridNode.prototype.collapse):
(WebInspector.TimelineDataGridNode.prototype.expand):
(WebInspector.TimelineDataGridNode.prototype.appendChild):
(WebInspector.TimelineDataGridNode.prototype.insertChild):
(WebInspector.TimelineDataGridNode.prototype.removeChild):
(WebInspector.TimelineDataGridNode.prototype.removeChildren):
(WebInspector.TimelineDataGridNode.prototype.removeChildrenRecursive):
(WebInspector.TimelineDataGridNode.prototype.refreshGraph.createBarsForRecords):
(WebInspector.TimelineDataGridNode.prototype.refreshGraph.else.collectRecordsByType.get if):
(WebInspector.TimelineDataGridNode.prototype.needsGraphRefresh):
(WebInspector.TimelineDataGridNode.prototype.isRecordVisible):
Support drawing the children records on the parent graph.

  • UserInterface/TimelineRecordBar.css:

(.timeline-record-bar.unfinished > .segment):
(:focus .selected .timeline-record-bar > .segment):
(:focus .selected .timeline-record-bar > .segment.inactive):
(:focus .selected .timeline-record-bar.has-inactive-segment > .segment:not(.inactive)):
Tweaked styles to look bettwen when selected.

  • UserInterface/TimelineRecordBar.js:

(WebInspector.TimelineRecordBar.recordsCannotBeCombined):
(WebInspector.TimelineRecordBar.prototype.set records):
(WebInspector.TimelineRecordBar.prototype.refresh):
Drive-by fixes for some bug with bars being reused.

Location:
trunk/Source/WebInspectorUI
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r162528 r162560  
     12014-01-22  Timothy Hatcher  <timothy@apple.com>
     2
     3        Support collapsing call site records into the resource timeline.
     4
     5        Also fix some filtering and graph issues.
     6
     7        https://bugs.webkit.org/show_bug.cgi?id=127440
     8
     9        Reviewed by Joseph Pecoraro.
     10
     11        * UserInterface/NavigationSidebarPanel.js:
     12        (WebInspector.NavigationSidebarPanel.prototype.updateFilter):
     13        (WebInspector.NavigationSidebarPanel.prototype.applyFiltersToTreeElement.matchTextFilter):
     14        (WebInspector.NavigationSidebarPanel.prototype.applyFiltersToTreeElement.makeVisible):
     15        (WebInspector.NavigationSidebarPanel.prototype.applyFiltersToTreeElement):
     16        (WebInspector.NavigationSidebarPanel.prototype._updateFilter):
     17        Tweak how filtering happens so custom filters never expand to reveal and auto expanded
     18        tree elements will auto-collapse again later even with custom filters.
     19
     20        * UserInterface/OverviewTimelineView.css:
     21        (.timeline-view.overview > .data-grid tr.parent:not(.expanded) td.graph-column .timeline-record-bar:not(.timeline-record-type-network) > .segment):
     22        (.timeline-view.overview > .data-grid tr.parent:not(.expanded).selected td.graph-column .timeline-record-bar:not(.timeline-record-type-network) > .segment):
     23        (.timeline-view.overview > .data-grid:focus tr.parent:not(.expanded).selected td.graph-column .timeline-record-bar:not(.timeline-record-type-network) > .segment):
     24        Add a shadow to provide some negative space between juxtaposed records. Only needed when not expanded.
     25
     26        * UserInterface/OverviewTimelineView.js:
     27        (WebInspector.OverviewTimelineView.prototype.updateLayout):
     28        (WebInspector.OverviewTimelineView.prototype._addResourceToTreeIfNeeded):
     29        Update the filter when current time changes and only auto expand the main resource.
     30
     31        * UserInterface/ResourceTimelineDataGridNode.js:
     32        (WebInspector.ResourceTimelineDataGridNode):
     33        (WebInspector.ResourceTimelineDataGridNode.prototype._timelineRecordUpdated):
     34        Don't schedule a refresh of the graph if the record isn't visible.
     35
     36        * UserInterface/SourceCodeTimelineTimelineDataGridNode.js:
     37        (WebInspector.SourceCodeTimelineTimelineDataGridNode):
     38        (WebInspector.SourceCodeTimelineTimelineDataGridNode.prototype._timelineRecordAdded):
     39        Don't schedule a refresh of the graph if the record isn't visible.
     40
     41        * UserInterface/TimelineContentView.js:
     42        (WebInspector.TimelineContentView.prototype._timeRangeSelectionChanged):
     43        Remove the boolean for updateFilter.
     44
     45        * UserInterface/TimelineDataGrid.js:
     46        (WebInspector.TimelineDataGrid.prototype._refreshDirtyDataGridNodes):
     47        (WebInspector.TimelineDataGrid.prototype._sort):
     48        Keep the hidden state in-sync between node and element.
     49
     50        * UserInterface/TimelineDataGridNode.js:
     51        (WebInspector.TimelineDataGridNode.prototype.collapse):
     52        (WebInspector.TimelineDataGridNode.prototype.expand):
     53        (WebInspector.TimelineDataGridNode.prototype.appendChild):
     54        (WebInspector.TimelineDataGridNode.prototype.insertChild):
     55        (WebInspector.TimelineDataGridNode.prototype.removeChild):
     56        (WebInspector.TimelineDataGridNode.prototype.removeChildren):
     57        (WebInspector.TimelineDataGridNode.prototype.removeChildrenRecursive):
     58        (WebInspector.TimelineDataGridNode.prototype.refreshGraph.createBarsForRecords):
     59        (WebInspector.TimelineDataGridNode.prototype.refreshGraph.else.collectRecordsByType.get if):
     60        (WebInspector.TimelineDataGridNode.prototype.needsGraphRefresh):
     61        (WebInspector.TimelineDataGridNode.prototype.isRecordVisible):
     62        Support drawing the children records on the parent graph.
     63
     64        * UserInterface/TimelineRecordBar.css:
     65        (.timeline-record-bar.unfinished > .segment):
     66        (:focus .selected .timeline-record-bar > .segment):
     67        (:focus .selected .timeline-record-bar > .segment.inactive):
     68        (:focus .selected .timeline-record-bar.has-inactive-segment > .segment:not(.inactive)):
     69        Tweaked styles to look better when selected.
     70
     71        * UserInterface/TimelineRecordBar.js:
     72        (WebInspector.TimelineRecordBar.recordsCannotBeCombined):
     73        (WebInspector.TimelineRecordBar.prototype.set records):
     74        (WebInspector.TimelineRecordBar.prototype.refresh):
     75        Drive-by fixes for some bug with bars being reused.
     76
    1772014-01-21  Timothy Hatcher  <timothy@apple.com>
    278
  • trunk/Source/WebInspectorUI/UserInterface/NavigationSidebarPanel.js

    r162414 r162560  
    293293    },
    294294
    295     updateFilter: function(dontExpandOnMatch)
    296     {
    297         this._updateFilter(dontExpandOnMatch);
     295    updateFilter: function()
     296    {
     297        this._updateFilter();
    298298    },
    299299
     
    310310    },
    311311
    312     applyFiltersToTreeElement: function(treeElement, dontExpandOnMatch)
     312    applyFiltersToTreeElement: function(treeElement)
    313313    {
    314314        if (!this._filterBar.hasActiveFilters() && !this.hasCustomFilters()) {
     
    326326
    327327        var filterableData = treeElement.filterableData || {};
     328
     329        var matchedBuiltInFilters = false;
    328330
    329331        var self = this;
     
    341343                if (!input)
    342344                    continue;
    343                 if (self._textFilterRegex.test(input))
     345                if (self._textFilterRegex.test(input)) {
     346                    matchedBuiltInFilters = true;
    344347                    return true;
     348                }
    345349            }
    346350
     
    359363                currentAncestor.hidden = false;
    360364
    361                 if (!currentAncestor.expanded && !dontExpandOnMatch) {
     365                // Only expand if the built-in filters matched, not custom filters.
     366                if (matchedBuiltInFilters && !currentAncestor.expanded) {
    362367                    currentAncestor.__wasExpandedDuringFiltering = true;
    363368                    currentAncestor.expand();
     
    371376            // Make this element visible since it matches.
    372377            makeVisible();
     378
     379            // If this tree element didn't match a built-in filter and was expanded earlier during filtering, collapse it again.
     380            if (!matchedBuiltInFilters && treeElement.expanded && treeElement.__wasExpandedDuringFiltering) {
     381                delete treeElement.__wasExpandedDuringFiltering;
     382                treeElement.collapse();
     383            }
     384
    373385            return;
    374386        }
     
    469481    },
    470482
    471     _updateFilter: function(dontExpandOnMatch)
     483    _updateFilter: function()
    472484    {
    473485        var filters = this._filterBar.filters;
     
    478490        var currentTreeElement = this._contentTreeOutline.children[0];
    479491        while (currentTreeElement && !currentTreeElement.root) {
    480             this.applyFiltersToTreeElement(currentTreeElement, dontExpandOnMatch);
     492            this.applyFiltersToTreeElement(currentTreeElement);
    481493            currentTreeElement = currentTreeElement.traverseNextTreeElement(false, null, false);
    482494        }
  • trunk/Source/WebInspectorUI/UserInterface/OverviewTimelineView.css

    r162412 r162560  
    7070    top: 2px;
    7171}
     72
     73.timeline-view.overview > .data-grid tr.parent:not(.expanded) td.graph-column .timeline-record-bar:not(.has-inactive-segment) > .segment {
     74    box-shadow: white 0 0 0 1px;
     75}
     76
     77.timeline-view.overview > .data-grid tr.parent:not(.expanded).selected td.graph-column .timeline-record-bar:not(.has-inactive-segment) > .segment {
     78    box-shadow: rgb(212, 212, 212) 0 0 0 1px;
     79}
     80
     81.timeline-view.overview > .data-grid:focus tr.parent:not(.expanded).selected td.graph-column .timeline-record-bar:not(.has-inactive-segment) > .segment {
     82    box-shadow: rgb(56, 121, 217) 0 0 0 1px;
     83}
     84
     85.timeline-view.overview > .data-grid tr.parent:not(.expanded) td.graph-column .timeline-record-bar.has-inactive-segment > .segment:not(.inactive) {
     86    box-shadow: white 1px 0 0;
     87}
     88
     89.timeline-view.overview > .data-grid tr.parent:not(.expanded).selected td.graph-column .timeline-record-bar.has-inactive-segment > .segment:not(.inactive) {
     90    box-shadow: rgb(212, 212, 212) 1px 0 0;
     91}
     92
     93.timeline-view.overview > .data-grid:focus tr.parent:not(.expanded).selected td.graph-column .timeline-record-bar.has-inactive-segment > .segment:not(.inactive) {
     94    box-shadow: rgb(56, 121, 217) 1px 0 0;
     95}
  • trunk/Source/WebInspectorUI/UserInterface/OverviewTimelineView.js

    r162527 r162560  
    9494        // We only need to refresh the graphs when the any of the times change.
    9595        if (this.zeroTime !== oldZeroTime || this.startTime !== oldStartTime || this.endTime !== oldEndTime || this.currentTime !== oldCurrentTime) {
    96             var item = this._dataGrid.children[0];
    97             while (item) {
    98                 item.refreshGraph();
    99                 item = item.traverseNextNode(false, null, true);
     96            var dataGridNode = this._dataGrid.children[0];
     97            while (dataGridNode) {
     98                dataGridNode.refreshGraph();
     99                dataGridNode = dataGridNode.traverseNextNode(true, null, true);
    100100            }
     101        }
     102
     103        if (!this.currentTime !== oldCurrentTime) {
     104            // Check the filters again since the current time change might have revealed this node. Start and end time changes are handled by TimelineContentView.
     105            WebInspector.timelineSidebarPanel.updateFilter();
    101106        }
    102107
     
    217222            return;
    218223
    219         if (parentFrame.mainResource === resource || parentFrame.provisionalMainResource === resource)
     224        var expandedByDefault = false;
     225        if (parentFrame.mainResource === resource || parentFrame.provisionalMainResource === resource) {
    220226            parentFrame = parentFrame.parentFrame;
     227            expandedByDefault = !parentFrame; // Main frame expands by default.
     228        }
    221229
    222230        var resourceTreeElement = new WebInspector.ResourceTreeElement(resource);
    223         resourceTreeElement.expand();
     231        if (expandedByDefault)
     232            resourceTreeElement.expand();
    224233
    225234        var resourceTimelineRecord = this._networkTimeline ? this._networkTimeline.recordForResource(resource) : null;
  • trunk/Source/WebInspectorUI/UserInterface/ResourceTimelineDataGridNode.js

    r162415 r162560  
    3131    this._record = resourceTimelineRecord;
    3232
    33     this._record.addEventListener(WebInspector.TimelineRecord.Event.Updated, graphOnly ? this.needsGraphRefresh : this._needsRefresh, this);
     33    this._record.addEventListener(WebInspector.TimelineRecord.Event.Updated, graphOnly ? this._timelineRecordUpdated : this._needsRefresh, this);
    3434
    3535    if (!graphOnly) {
     
    183183    {
    184184        WebInspector.resourceSidebarPanel.showSourceCode(this._resource);
     185    },
     186
     187    _timelineRecordUpdated: function(event)
     188    {
     189        if (this.isRecordVisible(this._record))
     190            this.needsGraphRefresh();
    185191    }
    186192};
  • trunk/Source/WebInspectorUI/UserInterface/SourceCodeTimelineTimelineDataGridNode.js

    r162412 r162560  
    2929
    3030    this._sourceCodeTimeline = sourceCodeTimeline;
    31     this._sourceCodeTimeline.addEventListener(WebInspector.Timeline.Event.RecordAdded, this.needsGraphRefresh, this);
     31    this._sourceCodeTimeline.addEventListener(WebInspector.Timeline.Event.RecordAdded, this._timelineRecordAdded, this);
    3232};
    3333
     
    5353    {
    5454        return {graph: this._sourceCodeTimeline.startTime};
     55    },
     56
     57    // Private
     58
     59    _timelineRecordAdded: function(event)
     60    {
     61        if (this.isRecordVisible(event.data.record))
     62            this.needsGraphRefresh();
    5563    }
    5664};
  • trunk/Source/WebInspectorUI/UserInterface/TimelineContentView.js

    r162527 r162560  
    405405
    406406        // Delay until the next frame to stay in sync with the current timeline view's time-based layout changes.
    407         requestAnimationFrame(function() { WebInspector.timelineSidebarPanel.updateFilter(true); });
     407        requestAnimationFrame(function() { WebInspector.timelineSidebarPanel.updateFilter(); });
    408408    }
    409409};
  • trunk/Source/WebInspectorUI/UserInterface/TimelineDataGrid.js

    r162527 r162560  
    239239            this.insertChild(dataGridNode, insertionIndex);
    240240
     241            // Adding the tree element back to the tree outline subjects it to filters.
     242            // Make sure we keep the hidden state in-sync while the synchronizer is disabled.
     243            dataGridNode.element.classList.toggle("hidden", treeElement.hidden);
     244
    241245            if (dataGridNode === selectedNode) {
    242246                selectedNode.revealAndSelect();
     
    275279            treeOutline.appendChild(treeElement);
    276280            this.appendChild(dataGridNode);
     281
     282            // Adding the tree element back to the tree outline subjects it to filters.
     283            // Make sure we keep the hidden state in-sync while the synchronizer is disabled.
     284            dataGridNode.element.classList.toggle("hidden", treeElement.hidden);
    277285        }
    278286
  • trunk/Source/WebInspectorUI/UserInterface/TimelineDataGridNode.js

    r162419 r162560  
    6565    },
    6666
     67    collapse: function()
     68    {
     69        WebInspector.DataGridNode.prototype.collapse.call(this);
     70
     71        // Refresh to show child bars in our graph now that we collapsed.
     72        this.refreshGraph();
     73    },
     74
     75    expand: function()
     76    {
     77        WebInspector.DataGridNode.prototype.expand.call(this);
     78
     79        if (!this.revealed)
     80            return;
     81
     82        // Refresh to remove child bars from our graph now that we expanded.
     83        this.refreshGraph();
     84
     85        // Refresh child graphs since they haven't been updating while we were collapsed.
     86        var childNode = this.children[0];
     87        while (childNode) {
     88            if (childNode instanceof WebInspector.TimelineDataGridNode)
     89                childNode.refreshGraph();
     90            childNode = childNode.traverseNextNode(true, this);
     91        }
     92    },
     93
    6794    createCellContent: function(columnIdentifier, cell)
    6895    {
     
    199226        }
    200227
    201         var records = this.records;
    202         if (!records || !records.length)
    203             return;
    204 
    205         // Fast path for single records.
    206         if (records.length === 1) {
    207             var record = records[0];
    208             var timelineRecordBar = this._timelineRecordBars[0];
    209 
    210             if (timelineRecordBar && timelineRecordBar.record !== record) {
    211                 timelineRecordBar.element.remove();
    212                 timelineRecordBar = null;
    213             }
    214 
    215             if (!timelineRecordBar)
    216                 timelineRecordBar = this._timelineRecordBars[0] = new WebInspector.TimelineRecordBar(record);
    217 
    218             if (timelineRecordBar.refresh(this._graphDataSource)) {
    219                 if (!timelineRecordBar.element.parentNode)
    220                     this._graphContainerElement.appendChild(timelineRecordBar.element);
    221             } else
    222                 timelineRecordBar.element.remove();
    223 
    224             return;
    225         }
    226 
    227         // Multiple records attempt to share a bar if their time is close to prevent overlapping bars.
     228        if (!this.revealed) {
     229            // We are not visible, but an ancestor will be drawing our graph.
     230            // Notify the next visible ancestor to refresh their graph.
     231            var ancestor = this;
     232            while (ancestor && !ancestor.root) {
     233                if (ancestor.revealed && ancestor instanceof WebInspector.TimelineDataGridNode) {
     234                    ancestor.refreshGraph();
     235                    return;
     236                }
     237
     238                ancestor = ancestor.parent;
     239            }
     240
     241            return;
     242        }
     243
    228244        var startTime = this._graphDataSource.startTime;
    229245        var currentTime = this._graphDataSource.currentTime;
     
    232248        var visibleWidth = this._graphContainerElement.offsetWidth;
    233249        var secondsPerPixel = duration / visibleWidth;
    234 
    235250        var recordBarIndex = 0;
    236         var barRecords = [];
    237251
    238252        function createBar(barRecords)
     
    248262        }
    249263
    250         for (var record of records) {
    251             // Combining multiple record bars is not supported with records that have inactive time.
    252             // ResourceTimelineRecord is the only one right, and it is always a single record handled above.
    253             console.assert(!record.usesActiveStartTime);
    254 
    255             if (isNaN(record.startTime))
    256                 continue;
    257 
    258             // If this bar is completely before the bounds of the graph, skip this record.
    259             if (record.endTime < startTime)
    260                 continue;
    261 
    262             // If this record is completely after the current time or end time, break out now.
    263             // Records are sorted, so all records after this will be beyond the current or end time too.
    264             if (record.startTime > currentTime || record.startTime > endTime)
    265                 break;
    266 
    267             // Check if the previous record can be combined with the current record, if not make a new bar.
    268             if (barRecords.length && WebInspector.TimelineRecordBar.recordsCannotBeCombined(barRecords, record, secondsPerPixel)) {
     264        function createBarsForRecords(records)
     265        {
     266            var barRecords = [];
     267
     268            for (var record of records) {
     269                if (isNaN(record.startTime))
     270                    continue;
     271
     272                // If this bar is completely before the bounds of the graph, skip this record.
     273                if (record.endTime < startTime)
     274                    continue;
     275
     276                // If this record is completely after the current time or end time, break out now.
     277                // Records are sorted, so all records after this will be beyond the current or end time too.
     278                if (record.startTime > currentTime || record.startTime > endTime)
     279                    break;
     280
     281                // Check if the previous record can be combined with the current record, if not make a new bar.
     282                if (barRecords.length && WebInspector.TimelineRecordBar.recordsCannotBeCombined(barRecords, record, secondsPerPixel)) {
     283                    createBar.call(this, barRecords);
     284                    barRecords = [];
     285                }
     286
     287                barRecords.push(record);
     288            }
     289
     290            // Create the bar for the last record if needed.
     291            if (barRecords.length)
    269292                createBar.call(this, barRecords);
    270                 barRecords = [];
    271             }
    272 
    273             barRecords.push(record);
    274         }
    275 
    276         // Create the bar for the last record if needed.
    277         if (barRecords.length)
    278             createBar.call(this, barRecords);
     293        }
     294
     295        if (this.expanded) {
     296            // When expanded just use the records for this node.
     297            createBarsForRecords.call(this, this.records);
     298        } else {
     299            // When collapsed use the records for this node and its descendants.
     300            // To share bars better, group records by type.
     301
     302            var recordTypeMap = new Map;
     303
     304            function collectRecordsByType(records)
     305            {
     306                for (var record of records) {
     307                    var typedRecords = recordTypeMap.get(record.type);
     308                    if (!typedRecords) {
     309                        typedRecords = [];
     310                        recordTypeMap.set(record.type, typedRecords);
     311                    }
     312
     313                    typedRecords.push(record);
     314                }
     315            }
     316
     317            collectRecordsByType(this.records);
     318
     319            var childNode = this.children[0];
     320            while (childNode) {
     321                if (childNode instanceof WebInspector.TimelineDataGridNode)
     322                    collectRecordsByType(childNode.records);
     323                childNode = childNode.traverseNextNode(false, this);
     324            }
     325
     326            for (var records of recordTypeMap.values())
     327                createBarsForRecords.call(this, records);
     328        }
    279329
    280330        // Remove the remaining unused TimelineRecordBars.
     
    291341
    292342        this._scheduledGraphRefreshIdentifier = requestAnimationFrame(this.refreshGraph.bind(this));
     343    },
     344
     345    // Protected
     346
     347    isRecordVisible: function(record)
     348    {
     349        if (!this._graphDataSource)
     350            return false;
     351
     352        if (isNaN(record.startTime))
     353            return false;
     354
     355        // If this bar is completely before the bounds of the graph, not visible.
     356        if (record.endTime < this.graphDataSource.startTime)
     357            return false;
     358
     359        // If this record is completely after the current time or end time, not visible.
     360        if (record.startTime > this.graphDataSource.currentTime || record.startTime > this.graphDataSource.endTime)
     361            return false;
     362
     363        return true;
    293364    }
    294365};
  • trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.css

    r162419 r162560  
    3636    border-radius: 3px;
    3737    min-width: 4px;
     38    z-index: 1;
    3839}
    3940
     
    4344}
    4445
     46.timeline-record-bar > .segment.inactive {
     47    z-index: 0;
     48}
     49
    4550.timeline-record-bar > .segment.inactive,
    4651.timeline-record-bar.unfinished > .segment {
     
    4853    border-bottom-right-radius: 0 !important;
    4954    border-right: none;
     55    margin-right: -1px;
    5056}
    5157
     
    5763:focus .selected .timeline-record-bar > .segment {
    5864    background-color: white !important;
    59     border-color: white !important;
     65    border: none !important;
     66}
     67
     68:focus .selected .timeline-record-bar > .segment.inactive {
     69    opacity: 0.7;
     70}
     71
     72:focus .selected .timeline-record-bar.has-inactive-segment > .segment:not(.inactive) {
     73    border-left: 1px solid rgba(56, 121, 217, 0.7) !important;
    6074}
    6175
  • trunk/Source/WebInspectorUI/UserInterface/TimelineRecordBar.js

    r162419 r162560  
    5959        return true;
    6060
     61    if (candidateRecord.usesActiveStartTime)
     62        return true;
     63
    6164    var lastRecord = records.lastValue;
     65    if (lastRecord.usesActiveStartTime)
     66        return true;
     67
    6268    if (lastRecord.type !== candidateRecord.type)
    6369        return true;
     
    113119                this._inactiveBarElement.classList.add(WebInspector.TimelineRecordBar.InactiveStyleClassName);
    114120                this._element.classList.add(WebInspector.TimelineRecordBar.HasInactiveSegmentStyleClassName);
    115                 this._element.insertBefore(this._inactiveBarElement, this._activeBarElement);
     121                this._element.insertBefore(this._inactiveBarElement, this._element.firstChild);
    116122            }
    117123        } else if (this._inactiveBarElement) {
     124            this._element.classList.remove(WebInspector.TimelineRecordBar.HasInactiveSegmentStyleClassName);
    118125            this._inactiveBarElement.remove();
    119126            delete this._inactiveBarElement;
     
    166173        this._updateElementPosition(this._element, newBarWidth, "width");
    167174
    168         if (!this._inactiveBarElement)
     175        if (!this._inactiveBarElement) {
     176            // If this TimelineRecordBar is reused and had an inactive bar previously,
     177            // we might need to remove some styles and add the active element back.
     178            this._activeBarElement.style.removeProperty("left");
     179            this._activeBarElement.style.removeProperty("width");
     180            if (!this._activeBarElement.parentNode)
     181                this._element.appendChild(this._activeBarElement);
    169182            return true;
     183        }
    170184
    171185        console.assert(firstRecord === lastRecord);
Note: See TracChangeset for help on using the changeset viewer.