Changeset 183721 in webkit


Ignore:
Timestamp:
May 2, 2015 12:26:21 PM (9 years ago)
Author:
commit-queue@webkit.org
Message:

Web Inspector: Relocate the selected range details in the Rendering Frames timeline UI
https://bugs.webkit.org/show_bug.cgi?id=144346

This patch removes the details sidebar used by the rendering frames view, and relocates the frame selection
chart the Timelines navigation sidebar.

Patch by Matt Baker <Matt Baker> on 2015-05-02
Reviewed by Timothy Hatcher.

  • Localizations/en.lproj/localizedStrings.js:
  • UserInterface/Base/Main.js:

(WebInspector.contentLoaded):
RenderingFramesDetailsSidebar is no longer used.

  • UserInterface/Controllers/TimelineManager.js:

(WebInspector.TimelineManager.prototype._loadNewRecording):
Reordered timelines.

  • UserInterface/Main.html:

Removed references to deleted files.

  • UserInterface/Views/ChartDetailsSectionLegendRow.js: Removed.

No longer used. The legend is now a child element of the chart.

  • UserInterface/Views/ChartDetailsSectionRow.css:

(.details-section > .content > .group > .row.chart > .title):
(.details-section > .content > .group > .row.chart > .chart-content):
(.details-section > .content > .group > .row.chart > .chart-content > .legend):
(.details-section > .content > .group > .row.chart > .chart-content > .legend > .legend-item):
(.details-section > .content > .group > .row.chart > .chart-content > .legend > .legend-item > .label > .color-swatch):
(.details-section > .content > .group > .row.chart > .chart-content > .legend > .legend-item > .label):
(.details-section > .content > .group > .row.chart > .chart-content > .legend > .legend-item > .value):
(.details-section > .content > .group > .row.chart > .chart-content > .legend > .legend-item > *):
New chart and legend styles.

  • UserInterface/Views/ChartDetailsSectionRow.js:

(WebInspector.ChartDetailsSectionRow):
(WebInspector.ChartDetailsSectionRow.prototype.set title):
(WebInspector.ChartDetailsSectionRow.prototype.set innerLabel):
(WebInspector.ChartDetailsSectionRow.prototype.set innerRadius):
(WebInspector.ChartDetailsSectionRow.prototype.get total):
(WebInspector.ChartDetailsSectionRow.set data):
(WebInspector.ChartDetailsSectionRow.prototype.set data):
(WebInspector.ChartDetailsSectionRow.prototype._createLegendItem):
(WebInspector.ChartDetailsSectionRow.prototype._refresh):

A few changes have been made to the appearance and behavior of the chart. A chart title can now be set,
and the legend appears to the right of the chart rather than in a separate details group.

The chart now has better support for adding empty data points, ensuring that a meaningful legend is shown even
when no rendering frames are selected in the timeline overview graph. This ensures that the task associated
with each colored frame segment is apparent, without having to make a selection or record a timeline.

  • UserInterface/Views/RenderingFrameDetailsSidebarPanel.js: Removed.

No longer used.

  • UserInterface/Views/RenderingFrameTimelineOverviewGraph.js:

Reduced maximum timeline height to increase the height of short frames.

  • UserInterface/Views/RenderingFrameTimelineView.js:

(WebInspector.RenderingFrameTimelineView.prototype.shown):
(WebInspector.RenderingFrameTimelineView.prototype.hidden):
RenderingFramesDetailsSidebar is no longer used.

  • UserInterface/Views/TimelineRecordingContentView.js:

(WebInspector.TimelineRecordingContentView):
(WebInspector.TimelineRecordingContentView.prototype._updateTimes):
(WebInspector.TimelineRecordingContentView.prototype._updateTimelineOverviewHeight):
(WebInspector.TimelineRecordingContentView.prototype._timelineRemoved):
(WebInspector.TimelineRecordingContentView.prototype._timeRangeSelectionChanged):
(WebInspector.TimelineRecordingContentView.prototype._updateFrameSelection):
Improved logic for updating the frame selection.

  • UserInterface/Views/TimelineSidebarPanel.css:

(.sidebar > .panel.navigation.timeline > .timelines-content > .details-section > div.header):
(.sidebar > .panel.navigation.timeline > .timelines-content > .details-section > .content > .group > .row.chart):
(.sidebar > .panel.navigation.timeline > .timelines-content > .details-section > .content > .group > .row.chart > .chart-content > .chart):
(.sidebar > .panel.navigation.timeline.timeline-recording-content-view-showing > .content): Deleted.
New chart styles.

  • UserInterface/Views/TimelineSidebarPanel.js:

(WebInspector.TimelineSidebarPanel):
(WebInspector.TimelineSidebarPanel.prototype.shown):
(WebInspector.TimelineSidebarPanel._timelineAdded.set this):
(WebInspector.TimelineSidebarPanel.this._timelineTreeElementMap.get select):
(WebInspector.TimelineSidebarPanel.get else):
(WebInspector.TimelineSidebarPanel._refreshFrameSelectionChart.getSelectedRecords.get var):
(WebInspector.TimelineSidebarPanel._refreshFrameSelectionChart.getSelectedRecords):
(WebInspector.TimelineSidebarPanel.showTimelineViewForTimeline.this._timelineTreeElementMap.get select):
(WebInspector.TimelineSidebarPanel.prototype.treeElementForRepresentedObject.get if.get if):
(WebInspector.TimelineSidebarPanel.prototype.treeElementForRepresentedObject.get if):
(WebInspector.TimelineSidebarPanel._refreshFrameSelectionChart.durationForRecordType):
(WebInspector.TimelineSidebarPanel.prototype.treeElementForRepresentedObject):
(WebInspector.TimelineSidebarPanel.set contentTreeOutlineLabel): Deleted.
(WebInspector.TimelineSidebarPanel._recordingCreated.set this): Deleted.
(WebInspector.TimelineSidebarPanel.get this): Deleted.
Moved the selected frames chart to the navigation sidebar.

  • UserInterface/Views/TimelineTabContentView.js:

(WebInspector.TimelineTabContentView):
RenderingFramesDetailsSidebar is no longer used.

  • WebInspectorUI.vcxproj/WebInspectorUI.vcxproj:
  • WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters:

Removed references to deleted files.

Location:
trunk/Source/WebInspectorUI
Files:
2 deleted
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r183714 r183721  
     12015-05-02  Matt Baker  <mattbaker@apple.com>
     2
     3        Web Inspector: Relocate the selected range details in the Rendering Frames timeline UI
     4        https://bugs.webkit.org/show_bug.cgi?id=144346
     5
     6        This patch removes the details sidebar used by the rendering frames view, and relocates the frame selection
     7        chart the Timelines navigation sidebar.
     8
     9        Reviewed by Timothy Hatcher.
     10
     11        * Localizations/en.lproj/localizedStrings.js:
     12        * UserInterface/Base/Main.js:
     13        (WebInspector.contentLoaded):
     14        RenderingFramesDetailsSidebar is no longer used.
     15
     16        * UserInterface/Controllers/TimelineManager.js:
     17        (WebInspector.TimelineManager.prototype._loadNewRecording):
     18        Reordered timelines.
     19
     20        * UserInterface/Main.html:
     21        Removed references to deleted files.
     22
     23        * UserInterface/Views/ChartDetailsSectionLegendRow.js: Removed.
     24        No longer used. The legend is now a child element of the chart.
     25
     26        * UserInterface/Views/ChartDetailsSectionRow.css:
     27        (.details-section > .content > .group > .row.chart > .title):
     28        (.details-section > .content > .group > .row.chart > .chart-content):
     29        (.details-section > .content > .group > .row.chart > .chart-content > .legend):
     30        (.details-section > .content > .group > .row.chart > .chart-content > .legend > .legend-item):
     31        (.details-section > .content > .group > .row.chart > .chart-content > .legend > .legend-item > .label > .color-swatch):
     32        (.details-section > .content > .group > .row.chart > .chart-content > .legend > .legend-item > .label):
     33        (.details-section > .content > .group > .row.chart > .chart-content > .legend > .legend-item > .value):
     34        (.details-section > .content > .group > .row.chart > .chart-content > .legend > .legend-item > *):
     35        New chart and legend styles.
     36
     37        * UserInterface/Views/ChartDetailsSectionRow.js:
     38        (WebInspector.ChartDetailsSectionRow):
     39        (WebInspector.ChartDetailsSectionRow.prototype.set title):
     40        (WebInspector.ChartDetailsSectionRow.prototype.set innerLabel):
     41        (WebInspector.ChartDetailsSectionRow.prototype.set innerRadius):
     42        (WebInspector.ChartDetailsSectionRow.prototype.get total):
     43        (WebInspector.ChartDetailsSectionRow.set data):
     44        (WebInspector.ChartDetailsSectionRow.prototype.set data):
     45        (WebInspector.ChartDetailsSectionRow.prototype._createLegendItem):
     46        (WebInspector.ChartDetailsSectionRow.prototype._refresh):
     47
     48        A few changes have been made to the appearance and behavior of the chart. A chart title can now be set,
     49        and the legend appears to the right of the chart rather than in a separate details group.
     50
     51        The chart now has better support for adding empty data points, ensuring that a meaningful legend is shown even
     52        when no rendering frames are selected in the timeline overview graph. This ensures that the task associated
     53        with each colored frame segment is apparent, without having to make a selection or record a timeline.
     54
     55        * UserInterface/Views/RenderingFrameDetailsSidebarPanel.js: Removed.
     56        No longer used.
     57
     58        * UserInterface/Views/RenderingFrameTimelineOverviewGraph.js:
     59        Reduced maximum timeline height to increase the height of short frames.
     60
     61        * UserInterface/Views/RenderingFrameTimelineView.js:
     62        (WebInspector.RenderingFrameTimelineView.prototype.shown):
     63        (WebInspector.RenderingFrameTimelineView.prototype.hidden):
     64        RenderingFramesDetailsSidebar is no longer used.
     65
     66        * UserInterface/Views/TimelineRecordingContentView.js:
     67        (WebInspector.TimelineRecordingContentView):
     68        (WebInspector.TimelineRecordingContentView.prototype._updateTimes):
     69        (WebInspector.TimelineRecordingContentView.prototype._updateTimelineOverviewHeight):
     70        (WebInspector.TimelineRecordingContentView.prototype._timelineRemoved):
     71        (WebInspector.TimelineRecordingContentView.prototype._timeRangeSelectionChanged):
     72        (WebInspector.TimelineRecordingContentView.prototype._updateFrameSelection):
     73        Improved logic for updating the frame selection.
     74
     75        * UserInterface/Views/TimelineSidebarPanel.css:
     76        (.sidebar > .panel.navigation.timeline > .timelines-content > .details-section > div.header):
     77        (.sidebar > .panel.navigation.timeline > .timelines-content > .details-section > .content > .group > .row.chart):
     78        (.sidebar > .panel.navigation.timeline > .timelines-content > .details-section > .content > .group > .row.chart > .chart-content > .chart):
     79        (.sidebar > .panel.navigation.timeline.timeline-recording-content-view-showing > .content): Deleted.
     80        New chart styles.
     81
     82        * UserInterface/Views/TimelineSidebarPanel.js:
     83        (WebInspector.TimelineSidebarPanel):
     84        (WebInspector.TimelineSidebarPanel.prototype.shown):
     85        (WebInspector.TimelineSidebarPanel._timelineAdded.set this):
     86        (WebInspector.TimelineSidebarPanel.this._timelineTreeElementMap.get select):
     87        (WebInspector.TimelineSidebarPanel.get else):
     88        (WebInspector.TimelineSidebarPanel._refreshFrameSelectionChart.getSelectedRecords.get var):
     89        (WebInspector.TimelineSidebarPanel._refreshFrameSelectionChart.getSelectedRecords):
     90        (WebInspector.TimelineSidebarPanel.showTimelineViewForTimeline.this._timelineTreeElementMap.get select):
     91        (WebInspector.TimelineSidebarPanel.prototype.treeElementForRepresentedObject.get if.get if):
     92        (WebInspector.TimelineSidebarPanel.prototype.treeElementForRepresentedObject.get if):
     93        (WebInspector.TimelineSidebarPanel._refreshFrameSelectionChart.durationForRecordType):
     94        (WebInspector.TimelineSidebarPanel.prototype.treeElementForRepresentedObject):
     95        (WebInspector.TimelineSidebarPanel.set contentTreeOutlineLabel): Deleted.
     96        (WebInspector.TimelineSidebarPanel._recordingCreated.set this): Deleted.
     97        (WebInspector.TimelineSidebarPanel.get this): Deleted.
     98        Moved the selected frames chart to the navigation sidebar.
     99
     100        * UserInterface/Views/TimelineTabContentView.js:
     101        (WebInspector.TimelineTabContentView):
     102        RenderingFramesDetailsSidebar is no longer used.
     103
     104        * WebInspectorUI.vcxproj/WebInspectorUI.vcxproj:
     105        * WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters:
     106        Removed references to deleted files.
     107
    11082015-05-02  Timothy Hatcher  <timothy@apple.com>
    2109
  • trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js

    r183659 r183721  
    2323localizedStrings["%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)"] = "%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)";
    2424localizedStrings["%d matches"] = "%d matches";
    25 localizedStrings["%d – %d"] = "%d – %d";
    2625localizedStrings["%fpx"] = "%fpx";
    2726localizedStrings["%fpx²"] = "%fpx²";
     
    3130localizedStrings["%s Event Dispatched"] = "%s Event Dispatched";
    3231localizedStrings["%s Prototype"] = "%s Prototype";
    33 localizedStrings["%s – %s"] = "%s – %s";
    3432localizedStrings["(Index)"] = "(Index)";
    3533localizedStrings["(anonymous function)"] = "(anonymous function)";
     
    8987localizedStrings["Catch Variables"] = "Catch Variables";
    9088localizedStrings["Character Data"] = "Character Data";
    91 localizedStrings["Chart"] = "Chart";
    9289localizedStrings["Checked"] = "Checked";
    9390localizedStrings["Child Layers"] = "Child Layers";
     
    131128localizedStrings["Could not fetch properties. Object may no longer exist."] = "Could not fetch properties. Object may no longer exist.";
    132129localizedStrings["Create a new tab"] = "Create a new tab";
    133 localizedStrings["DOM Tree"] = "DOM Tree";
    134130localizedStrings["Data"] = "Data";
    135131localizedStrings["Data returned from the database is too large."] = "Data returned from the database is too large.";
     
    234230localizedStrings["Forward (%s)"] = "Forward (%s)";
    235231localizedStrings["Fragment"] = "Fragment";
    236 localizedStrings["Frame"] = "Frame";
    237232localizedStrings["Frame %d"] = "Frame %d";
    238233localizedStrings["Frame URL"] = "Frame URL";
     234localizedStrings["Frame: %d (%s – %s)"] = "Frame: %d (%s – %s)";
    239235localizedStrings["Frames"] = "Frames";
     236localizedStrings["Frames: %d – %d (%s – %s)"] = "Frames: %d – %d (%s – %s)";
     237localizedStrings["Frames: None Selected"] = "Frames: None Selected";
    240238localizedStrings["Full URL"] = "Full URL";
    241239localizedStrings["Function"] = "Function";
     
    420418localizedStrings["Selected"] = "Selected";
    421419localizedStrings["Selected Element"] = "Selected Element";
     420localizedStrings["Selected Frames"] = "Selected Frames";
    422421localizedStrings["Selected Item"] = "Selected Item";
    423422localizedStrings["Selected Items"] = "Selected Items";
    424 localizedStrings["Selected Range"] = "Selected Range";
    425423localizedStrings["Selected Symbol"] = "Selected Symbol";
    426424localizedStrings["Selected Value"] = "Selected Value";
     
    451449localizedStrings["Socket"] = "Socket";
    452450localizedStrings["Sockets"] = "Sockets";
    453 localizedStrings["Source Code"] = "Source Code";
    454451localizedStrings["Specificity: (%d, %d, %d)"] = "Specificity: (%d, %d, %d)";
    455452localizedStrings["Specificity: No value for selected element"] = "Specificity: No value for selected element";
     
    475472localizedStrings["Text Only"] = "Text Only";
    476473localizedStrings["The “%s”\ntable is empty."] = "The “%s”\ntable is empty.";
    477 localizedStrings["Time"] = "Time";
    478474localizedStrings["Timeline Events"] = "Timeline Events";
    479475localizedStrings["Timeline Recording %d"] = "Timeline Recording %d";
  • trunk/Source/WebInspectorUI/UserInterface/Base/Main.js

    r183714 r183721  
    316316    this.scopeChainDetailsSidebarPanel = new WebInspector.ScopeChainDetailsSidebarPanel;
    317317    this.probeDetailsSidebarPanel = new WebInspector.ProbeDetailsSidebarPanel;
    318     this.renderingFrameDetailsSidebarPanel = new WebInspector.RenderingFrameDetailsSidebarPanel;
    319318
    320319    if (window.LayerTreeAgent)
  • trunk/Source/WebInspectorUI/UserInterface/Controllers/TimelineManager.js

    r183579 r183721  
    423423        var newRecording = new WebInspector.TimelineRecording(identifier, WebInspector.UIString("Timeline Recording %d").format(identifier));
    424424        newRecording.addTimeline(WebInspector.Timeline.create(WebInspector.TimelineRecord.Type.Network, newRecording));
     425        newRecording.addTimeline(WebInspector.Timeline.create(WebInspector.TimelineRecord.Type.Layout, newRecording));
     426        newRecording.addTimeline(WebInspector.Timeline.create(WebInspector.TimelineRecord.Type.Script, newRecording));
    425427
    426428        // COMPATIBILITY (iOS 8): TimelineAgent.EventType.RenderingFrame did not exist.
    427429        if (window.TimelineAgent && TimelineAgent.EventType.RenderingFrame)
    428430            newRecording.addTimeline(WebInspector.Timeline.create(WebInspector.TimelineRecord.Type.RenderingFrame, newRecording));
    429 
    430         newRecording.addTimeline(WebInspector.Timeline.create(WebInspector.TimelineRecord.Type.Layout, newRecording));
    431         newRecording.addTimeline(WebInspector.Timeline.create(WebInspector.TimelineRecord.Type.Script, newRecording));
    432431
    433432        this._recordings.push(newRecording);
  • trunk/Source/WebInspectorUI/UserInterface/Main.html

    r183671 r183721  
    378378    <script src="Views/CSSStyleDetailsSidebarPanel.js"></script>
    379379    <script src="Views/CallFrameTreeElement.js"></script>
    380     <script src="Views/ChartDetailsSectionLegendRow.js"></script>
    381380    <script src="Views/ChartDetailsSectionRow.js"></script>
    382381    <script src="Views/ClusterContentView.js"></script>
     
    474473    <script src="Views/QuickConsoleNavigationBar.js"></script>
    475474    <script src="Views/RadioButtonNavigationItem.js"></script>
    476     <script src="Views/RenderingFrameDetailsSidebarPanel.js"></script>
    477475    <script src="Views/RenderingFrameTimelineDataGridNode.js"></script>
    478476    <script src="Views/RenderingFrameTimelineOverview.js"></script>
  • trunk/Source/WebInspectorUI/UserInterface/Views/ChartDetailsSectionRow.css

    r182660 r183721  
    2424 */
    2525
    26 .details-section .row.chart {
     26.details-section > .content > .group > .row.chart > .title {
     27    color: rgb(57, 57, 57);
     28
     29    white-space: nowrap;
     30    overflow: hidden;
    2731    text-align: center;
     32    text-overflow: ellipsis;
     33
     34    font-size: 11px;
     35
     36    padding: 4px 5px 0px 9px;
    2837}
    2938
    30 .details-section .row.chart canvas {
    31     width: 150px;
    32     height: 150px;
     39.details-section > .content > .group > .row.chart > .chart-content {
     40    display: flex;
     41    justify-content: center;
     42    padding: 8px 5px 0px 12px;
    3343}
    3444
    35 .details-section .row.chart.empty canvas {
    36     display: none;
     45.details-section > .content > .group > .row.chart > .chart-content > .legend {
     46    display: table;
     47    margin-left: 12px;
    3748}
    3849
    39 .details-section > .content > .group > .row.legend-item > .label > .color-swatch {
     50.details-section > .content > .group > .row.chart > .chart-content > .legend > .legend-item {
     51    display: table-row;
     52    height: 16px;
     53}
     54
     55.details-section > .content > .group > .row.chart > .chart-content > .legend > .legend-item > .label > .color-swatch {
    4056    display: inline-block;
    41     margin-left: 6px;
     57
    4258    width: 8px;
    4359    height: 8px;
     60    margin-right: 6px;
    4461
    45     border: solid 1px #666;
     62    border: solid 1px rgb(102, 102, 102);
    4663}
     64
     65.details-section > .content > .group > .row.chart > .chart-content > .legend > .legend-item > .label {
     66    color: rgb(51, 51, 51);
     67}
     68
     69.details-section > .content > .group > .row.chart > .chart-content > .legend > .legend-item > .value {
     70    padding-left: 8px;
     71}
     72
     73.details-section > .content > .group > .row.chart > .chart-content > .legend > .legend-item > * {
     74    display: table-cell;
     75    vertical-align: middle;
     76}
  • trunk/Source/WebInspectorUI/UserInterface/Views/ChartDetailsSectionRow.js

    r182660 r183721  
    2626WebInspector.ChartDetailsSectionRow = class ChartDetailsSectionRow extends WebInspector.DetailsSectionRow
    2727{
    28     constructor(formatValueCallback)
     28    constructor(delegate)
    2929    {
    3030        super(WebInspector.UIString("No Chart Available"));
     
    3232        this.element.classList.add("chart");
    3333
    34         this._legendGroup = new WebInspector.DetailsSectionGroup;
    35         this._formatValueCallback = formatValueCallback;
    36         this._chartItems = [];
     34        this._titleElement = document.createElement("div");
     35        this._titleElement.className = "title";
     36        this.element.appendChild(this._titleElement);
     37
     38        var chartContentElement = document.createElement("div");
     39        chartContentElement.className = "chart-content";
     40        this.element.appendChild(chartContentElement);
     41
     42        this._canvas = document.createElement("canvas");
     43        this._canvas.className = "chart";
     44        chartContentElement.appendChild(this._canvas);
     45
     46        this._legendElement = document.createElement("div");
     47        this._legendElement.className = "legend";
     48        chartContentElement.appendChild(this._legendElement);
     49
     50        this._delegate = delegate;
     51        this._items = [];
     52        this._title = "";
    3753        this._innerLabel = "";
    38         this._innerRadius = 0.5;
     54        this._innerRadius = 0;
    3955        this._innerLabelFontSize = 11;
    40         this._shadowColor = "rgba(0, 0, 0, 0.5)";
     56        this._shadowColor = "rgba(0, 0, 0, 0.6)";
    4157        this._total = 0;
     58    }
     59
     60    // Public
     61
     62    set title(title)
     63    {
     64        if (this._title === title)
     65            return;
     66
     67        this._title = title;
     68        this._titleElement.textContent = title;
     69    }
     70
     71    set innerLabel(label)
     72    {
     73        if (this._innerLabel === label)
     74            return;
     75
     76        this._innerLabel = label;
    4277
    4378        this._refresh();
    4479    }
    4580
    46     // Public
    47 
    48     get legendGroup()
     81    set innerRadius(radius)
    4982    {
    50         return this._legendGroup;
    51     }
    52 
    53     set innerLabel(x)
    54     {
    55         if (this._innerLabel === x)
     83        if (this._innerRadius === radius)
    5684            return;
    5785
    58         this._innerLabel = x;
     86        this._innerRadius = radius;
    5987
    6088        this._refresh();
    6189    }
    6290
    63     addChartValue(label, value, color)
     91    get total()
    6492    {
    65         console.assert(value >= 0);
    66         if (value < 0)
     93        return this._total;
     94    }
     95
     96    set data(items)
     97    {
     98        if (!(items instanceof Array))
     99            items = [items];
     100
     101        items = items.filter(function(item) { return item.value >= 0; });
     102        if (!this._items.length && !items.length)
    67103            return;
    68104
    69         this._chartItems.push({label, value, color});
    70         this._total += value
     105        if (this._items.length === items.length && this._items.every(function(item, index) { return JSON.stringify(item) === JSON.stringify(items[index]); }))
     106            return;
     107
     108        this._items = items;
     109        this._total = this._items.reduce(function(previousValue, currentValue) { return previousValue + currentValue.value; }, 0);;
     110
     111        this._legendElement.removeChildren();
     112        this._items.forEach(function(item) { this._legendElement.appendChild(this._createLegendItem(item)); }, this);
    71113
    72114        this._refresh();
    73 
    74         if (!this._legendGroup)
    75             return;
    76 
    77         var rows = this._legendGroup.rows;
    78         var formattedValue = this._formatValueCallback ? this._formatValueCallback(value) : value;
    79         rows.push(new WebInspector.ChartDetailsSectionLegendRow(label, formattedValue, color));
    80         this._legendGroup.rows = rows;
    81     }
    82 
    83     clearChart()
    84     {
    85         this._chartItems = [];
    86         this._total = 0;
    87 
    88         this._refresh();
    89 
    90         if (!this._legendGroup)
    91             return;
    92 
    93         this._legendGroup.rows = [];
    94115    }
    95116
    96117    // Private
    97118
     119    _createLegendItem(item)
     120    {
     121        var colorSwatchElement = document.createElement("div");
     122        colorSwatchElement.className = "color-swatch";
     123        colorSwatchElement.style.backgroundColor = item.color;
     124
     125        var labelElement = document.createElement("div");
     126        labelElement.className = "label";
     127        labelElement.appendChild(colorSwatchElement);
     128        labelElement.appendChild(document.createTextNode(item.label));
     129
     130        var valueElement = document.createElement("div");
     131        valueElement.className = "value";
     132
     133        if (this._delegate && typeof this._delegate.formatChartValue === "function")
     134            valueElement.textContent = this._delegate.formatChartValue(item.value);
     135        else
     136            valueElement.textContent = item.value;
     137
     138        var legendItemElement = document.createElement("div");
     139        legendItemElement.className = "legend-item";
     140        legendItemElement.appendChild(labelElement);
     141        legendItemElement.appendChild(valueElement);
     142
     143        return legendItemElement;
     144    }
     145
    98146    _refresh()
    99147    {
    100         if (!this._chartItems.length) {
    101             this._canvas = null;
    102             this.showEmptyMessage();
    103             return;
    104         }
    105 
    106         if (!this._canvas) {
    107             this.hideEmptyMessage();
    108 
    109             this._canvas = document.createElement("canvas");
    110             this.element.appendChild(this._canvas);
    111 
    112             this._canvas.width = this._canvas.offsetWidth * window.devicePixelRatio;
    113             this._canvas.height = this._canvas.offsetHeight * window.devicePixelRatio;
    114         }
     148        var width = this._canvas.clientWidth * window.devicePixelRatio;
     149        var height = this._canvas.clientHeight * window.devicePixelRatio;
     150        this._canvas.width = width;
     151        this._canvas.height = height;
    115152
    116153        var context = this._canvas.getContext("2d");
    117         context.clearRect(0, 0, this._canvas.width, this._canvas.height);
     154        context.clearRect(0, 0, width, height);
    118155
    119         var centerX = Math.floor(this._canvas.width / 2);
    120         var centerY = Math.floor(this._canvas.height / 2);
    121         var radius = Math.floor(Math.min(centerX, centerY) * 0.96);   // Add a small margin to prevent clipping of the chart shadow.
     156        var x = Math.floor(width / 2);
     157        var y = Math.floor(height / 2);
     158        var radius = Math.floor(Math.min(x, y) * 0.96);   // Add a small margin to prevent clipping of the chart shadow.
    122159        var innerRadius = Math.floor(radius * this._innerRadius);
    123160        var startAngle = 1.5 * Math.PI;
     
    139176        context.shadowOffsetY = window.devicePixelRatio;
    140177        context.shadowColor = this._shadowColor;
    141         drawSlice(centerX, centerY, 0, 2.0 * Math.PI, "rgb(255, 255, 255)");
     178        drawSlice(x, y, 0, 2.0 * Math.PI, "rgb(242, 242, 242)");
    142179        context.restore();
    143180
    144         for (var item of this._chartItems) {
     181        for (var item of this._items) {
     182            if (item.value === 0)
     183                continue;
    145184            endAngle += (item.value / this._total) * 2.0 * Math.PI;
    146             drawSlice(centerX, centerY, startAngle, endAngle, item.color);
     185            drawSlice(x, y, startAngle, endAngle, item.color);
    147186            startAngle = endAngle;
    148187        }
  • trunk/Source/WebInspectorUI/UserInterface/Views/RenderingFrameTimelineOverviewGraph.js

    r183469 r183721  
    4141
    4242WebInspector.RenderingFrameTimelineOverviewGraph.StyleClassName = "rendering-frame";
    43 WebInspector.RenderingFrameTimelineOverviewGraph.MaximumGraphHeightSeconds = 0.05;
     43WebInspector.RenderingFrameTimelineOverviewGraph.MaximumGraphHeightSeconds = 0.037;
    4444WebInspector.RenderingFrameTimelineOverviewGraph.MinimumGraphHeightSeconds = 0.0185;
    4545
  • trunk/Source/WebInspectorUI/UserInterface/Views/RenderingFrameTimelineView.js

    r183469 r183721  
    8787        WebInspector.ContentView.prototype.shown.call(this);
    8888
    89         WebInspector.renderingFrameDetailsSidebarPanel.renderingFrameTimeline = this.representedObject;
    90 
    9189        this._dataGrid.shown();
    9290    },
     
    9492    hidden: function()
    9593    {
    96         WebInspector.renderingFrameDetailsSidebarPanel.renderingFrameTimeline = null;
    97 
    9894        this._dataGrid.hidden();
    9995
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineRecordingContentView.js

    r183579 r183721  
    6363    this._lastUpdateTimestamp = NaN;
    6464    this._startTimeNeedsReset = true;
     65    this._renderingFrameTimeline = null;
    6566
    6667    this._recording.addEventListener(WebInspector.TimelineRecording.Event.TimelineAdded, this._timelineAdded, this);
     
    261262
    262263        if (this._timelineSidebarPanel.viewMode === WebInspector.TimelineSidebarPanel.ViewMode.RenderingFrames) {
    263             var timeline = this._getRenderingFrameTimeline();
    264             console.assert(timeline);
    265 
    266             if (timeline && timeline.records.length) {
     264            console.assert(this._renderingFrameTimeline);
     265
     266            if (this._renderingFrameTimeline && this._renderingFrameTimeline.records.length) {
     267                var records = this._renderingFrameTimeline.records;
    267268                var startIndex = Math.floor(startTime);
    268                 if (startIndex >= timeline.records.length)
     269                if (startIndex >= records.length)
    269270                    return false;
    270271
    271                 var endIndex = Math.min(Math.floor(endTime), timeline.records.length - 1);
     272                var endIndex = Math.min(Math.floor(endTime), records.length - 1);
    272273                console.assert(startIndex <= endIndex, startIndex);
    273274
    274                 startTime = timeline.records[startIndex].startTime;
    275                 endTime = timeline.records[endIndex].endTime;
     275                startTime = records[startIndex].startTime;
     276                endTime = records[endIndex].endTime;
    276277            }
    277278        }
     
    426427            this.currentTimelineView.currentTime = currentTime;
    427428
    428         var timeline = this._getRenderingFrameTimeline();
    429         if (timeline)
    430             this._renderingFrameTimelineOverview.endTime = timeline.records.length;
     429        if (this._renderingFrameTimeline && this.currentTimelineView.representedObject.type === WebInspector.TimelineRecord.Type.RenderingFrame) {
     430            var oldEndTime = this._renderingFrameTimelineOverview.endTime;
     431            this._renderingFrameTimelineOverview.endTime = this._renderingFrameTimeline.records.length;
     432        }
    431433
    432434        this._timelineSidebarPanel.updateFilter();
     
    537539        else {
    538540            var timelineCount = this._timelineViewMap.size;
    539             if (this._getRenderingFrameTimeline())
     541            if (this._renderingFrameTimeline)
    540542                timelineCount--;
    541543
     
    548550    },
    549551
    550     _getRenderingFrameTimeline: function()
    551     {
    552         for (var timeline of this._timelineViewMap.keys()) {
    553             if (timeline.type === WebInspector.TimelineRecord.Type.RenderingFrame)
    554                 return timeline;
    555         }
    556 
    557         return null;
    558     },
    559 
    560552    _timelineAdded: function(timelineOrEvent)
    561553    {
     
    568560
    569561        this._timelineViewMap.set(timeline, new WebInspector.ContentView(timeline, {timelineSidebarPanel: this._timelineSidebarPanel}));
     562        if (timeline.type === WebInspector.TimelineRecord.Type.RenderingFrame)
     563            this._renderingFrameTimeline = timeline;
    570564
    571565        var pathComponent = new WebInspector.HierarchicalPathComponent(timeline.displayName, timeline.iconClassName, timeline);
     
    585579        if (this.currentTimelineView === timelineView)
    586580            this.showOverviewTimelineView();
     581        if (timeline.type === WebInspector.TimelineRecord.Type.RenderingFrame)
     582            this._renderingFrameTimeline = null;
    587583
    588584        this._pathComponentMap.delete(timeline);
     
    644640
    645641            if (this.currentTimelineView.representedObject.type === WebInspector.TimelineRecord.Type.RenderingFrame)
    646                 WebInspector.renderingFrameDetailsSidebarPanel.updateRangeSelection(this.currentTimelineView.startTime, this.currentTimelineView.endTime);
     642                this._updateFrameSelection();
    647643        }
    648644
     
    657653                this.dispatchEventToListeners(WebInspector.ContentView.Event.SelectionPathComponentsDidChange);
    658654        }.bind(this));
     655    },
     656
     657    _updateFrameSelection: function()
     658    {
     659        console.assert(this._renderingFrameTimeline);
     660        if (!this._renderingFrameTimeline)
     661            return;
     662
     663        var startIndex = this._renderingFrameTimelineOverview.selectionStartTime;
     664        var endIndex = startIndex + this._renderingFrameTimelineOverview.selectionDuration;
     665        this._timelineSidebarPanel.updateFrameSelection(startIndex, endIndex);
    659666    }
    660667};
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineSidebarPanel.css

    r183579 r183721  
    193193    right: -16px;
    194194}
     195
     196.sidebar > .panel.navigation.timeline > .timelines-content > .details-section > div.header {
     197    display: none;
     198}
     199
     200.sidebar > .panel.navigation.timeline > .timelines-content > .details-section > .content > .group > .row.chart {
     201    height: 108px;
     202}
     203
     204.sidebar > .panel.navigation.timeline > .timelines-content > .details-section > .content > .group > .row.chart > .chart-content > .chart {
     205    width: 76px;
     206    height: 76px;
     207}
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineSidebarPanel.js

    r183579 r183721  
    7979            container.appendChild(this._viewModeNavigationBar.element);
    8080            this.element.insertBefore(container, this.element.firstChild);
     81
     82            this._chartColors = {
     83                layout: "rgb(212, 108, 108)",
     84                script: "rgb(153, 113, 185)",
     85                other: "rgb(221, 221, 221)",
     86                idle: "rgb(255, 255, 255)"
     87            };
     88
     89            this._frameSelectionChartRow = new WebInspector.ChartDetailsSectionRow(this);
     90
     91            var chartGroup = new WebInspector.DetailsSectionGroup([this._frameSelectionChartRow]);
     92            this._frameSelectionChartSection = new WebInspector.DetailsSection("frames-selection-chart", WebInspector.UIString("Selected Frames"), [chartGroup], null, true);
     93            this._timelinesContentContainerElement.appendChild(this._frameSelectionChartSection.element);
    8194        } else {
    8295            var timelinesTitleBarElement = document.createElement("div");
     
    145158        if (this._displayedContentView)
    146159            this.contentBrowser.showContentView(this._displayedContentView);
     160
     161        if (this.viewMode === WebInspector.TimelineSidebarPanel.ViewMode.RenderingFrames)
     162            this._refreshFrameSelectionChart();
    147163    }
    148164
     
    256272
    257273        var selectedByUser = false;
    258         this._changeViewMode(this._viewModeForTimeline(null), selectedByUser);
     274        this._changeViewMode(WebInspector.TimelineSidebarPanel.ViewMode.Timelines, selectedByUser);
    259275    }
    260276
     
    263279        console.assert(timeline instanceof WebInspector.Timeline, timeline);
    264280        console.assert(this._displayedRecording.timelines.has(timeline.type), "Cannot show timeline because it does not belong to the shown recording.", timeline.type);
     281
     282        // The sidebar view mode must be in the correct state before changing the content view.
     283        var selectedByUser = false;
     284        this._changeViewMode(this._viewModeForTimeline(timeline), selectedByUser);
    265285
    266286        if (this._timelineTreeElementMap.has(timeline)) {
     
    273293            this.contentBrowser.showContentView(this._displayedContentView);
    274294        }
    275 
    276         var selectedByUser = false;
    277         this._changeViewMode(this._viewModeForTimeline(timeline), selectedByUser);
     295    }
     296
     297    updateFrameSelection(startFrameIndex, endFrameIndex)
     298    {
     299        console.assert(startFrameIndex <= endFrameIndex);
     300        console.assert(this.viewMode === WebInspector.TimelineSidebarPanel.ViewMode.RenderingFrames, this._viewMode);
     301
     302        startFrameIndex = Math.floor(startFrameIndex);
     303        endFrameIndex = Math.floor(endFrameIndex);
     304        if (this._startFrameIndex === startFrameIndex && this._endFrameIndex === endFrameIndex)
     305            return;
     306
     307        this._startFrameIndex = startFrameIndex;
     308        this._endFrameIndex = endFrameIndex;
     309
     310        this._refreshFrameSelectionChart();
     311    }
     312
     313    formatChartValue(value)
     314    {
     315        return this._frameSelectionChartRow.total === 0 ? "" : Number.secondsToString(value);
    278316    }
    279317
     
    374412    }
    375413
     414    _renderingFrameTimelineTimesUpdated(event)
     415    {
     416        if (this.viewMode === WebInspector.TimelineSidebarPanel.ViewMode.RenderingFrames)
     417            this._refreshFrameSelectionChart();
     418    }
     419
    376420    _timelinesTreeElementSelected(treeElement, selectedByUser)
    377421    {
     
    396440        var didShowTimelineRecordingContentView = this.contentBrowser.currentContentView instanceof WebInspector.TimelineRecordingContentView;
    397441        this.element.classList.toggle(WebInspector.TimelineSidebarPanel.TimelineRecordingContentViewShowingStyleClass, didShowTimelineRecordingContentView);
     442
     443        if (this.viewMode === WebInspector.TimelineSidebarPanel.ViewMode.RenderingFrames)
     444            this._refreshFrameSelectionChart();
    398445    }
    399446
     
    476523        console.assert(!this._timelineTreeElementMap.has(timeline), timeline);
    477524
    478         if (this._viewModeForTimeline(timeline) !== WebInspector.TimelineSidebarPanel.ViewMode.Timelines)
    479             return;
     525        if (timeline.type === WebInspector.TimelineRecord.Type.RenderingFrame) {
     526            timeline.addEventListener(WebInspector.Timeline.Event.TimesUpdated, this._renderingFrameTimelineTimesUpdated, this);
     527            return;
     528        }
    480529
    481530        var timelineTreeElement = new WebInspector.GeneralTreeElement([timeline.iconClassName, WebInspector.TimelineSidebarPanel.LargeIconStyleClass], timeline.displayName, null, timeline);
     
    496545        var timeline = event.data.timeline;
    497546        console.assert(timeline instanceof WebInspector.Timeline, timeline);
    498         if (this._viewModeForTimeline(timeline) !== WebInspector.TimelineSidebarPanel.ViewMode.Timelines)
    499             return;
     547
     548        if (timeline.type === WebInspector.TimelineRecord.Type.RenderingFrame) {
     549            timeline.removeEventListener(WebInspector.Timeline.Event.TimesUpdated, this._renderingFrameTimelineTimesUpdated, this);
     550            return;
     551        }
    500552
    501553        console.assert(this._timelineTreeElementMap.has(timeline), timeline);
     
    595647        this._viewModeNavigationBar.selectedNavigationItem = this._viewMode;
    596648
    597         if (this._viewMode === WebInspector.TimelineSidebarPanel.ViewMode.Timelines)
     649        if (this._viewMode === WebInspector.TimelineSidebarPanel.ViewMode.Timelines) {
    598650            this._timelinesTreeOutline.element.classList.remove(WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementHiddenStyleClassName);
    599         else
     651            this._frameSelectionChartSection.collapsed = true;
     652        } else {
    600653            this._timelinesTreeOutline.element.classList.add(WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementHiddenStyleClassName);
     654            this._frameSelectionChartSection.collapsed = false;
     655        }
    601656
    602657        if (!selectedByUser)
     
    614669        } else
    615670            this.showTimelineOverview();
     671    }
     672
     673    _refreshFrameSelectionChart()
     674    {
     675        if (!this.visible)
     676            return;
     677
     678        function getSelectedRecords()
     679        {
     680            console.assert(this._displayedRecording);
     681            console.assert(this._displayedRecording.timelines.has(WebInspector.TimelineRecord.Type.RenderingFrame), "Cannot find rendering frames timeline in displayed recording");
     682
     683            var timeline = this._displayedRecording.timelines.get(WebInspector.TimelineRecord.Type.RenderingFrame);
     684            var selectedRecords = [];
     685            for (var record of timeline.records) {
     686                console.assert(record instanceof WebInspector.RenderingFrameTimelineRecord);
     687                // If this frame is completely before the bounds of the graph, skip this record.
     688                if (record.frameIndex < this._startFrameIndex)
     689                    continue;
     690
     691                // If this record is completely after the end time, break out now.
     692                // Records are sorted, so all records after this will be beyond the end time too.
     693                if (record.frameIndex > this._endFrameIndex)
     694                    break;
     695
     696                selectedRecords.push(record);
     697            }
     698
     699            return selectedRecords;
     700        }
     701
     702        var chart = this._frameSelectionChartRow;
     703        var records = getSelectedRecords.call(this);
     704        if (!records.length) {
     705            this._frameSelectionChartRow.title = WebInspector.UIString("Frames: None Selected");
     706            this._frameSelectionChartRow.data = [
     707                {label: WebInspector.UIString("Layout"), value: 0, color: this._chartColors.layout},
     708                {label: WebInspector.UIString("Script"), value: 0, color: this._chartColors.script},
     709                {label: WebInspector.UIString("Other"), value: 0, color: this._chartColors.other},
     710                {label: WebInspector.UIString("Idle"), value: 0, color: this._chartColors.idle}
     711            ];
     712            return;
     713        }
     714
     715        var firstRecord = records[0];
     716        var lastRecord = records.lastValue;
     717
     718        if (records.length > 1) {
     719            this._frameSelectionChartRow.title = WebInspector.UIString("Frames: %d – %d (%s – %s)").format(firstRecord.frameNumber, lastRecord.frameNumber,
     720                Number.secondsToString(firstRecord.startTime), Number.secondsToString(lastRecord.endTime));
     721        } else {
     722            this._frameSelectionChartRow.title = WebInspector.UIString("Frame: %d (%s – %s)").format(firstRecord.frameNumber,
     723                Number.secondsToString(firstRecord.startTime), Number.secondsToString(lastRecord.endTime));
     724        }
     725
     726        function durationForRecordType(type)
     727        {
     728            return records.reduce(function(previousValue, currentValue) {
     729                return previousValue + (type ? currentValue.durationForRecords(type) : currentValue.durationRemainder);
     730            }, 0);
     731        }
     732
     733        var totalTime = lastRecord.endTime - firstRecord.startTime;
     734        var layoutTime = durationForRecordType(WebInspector.TimelineRecord.Type.Layout);
     735        var scriptTime = durationForRecordType(WebInspector.TimelineRecord.Type.Script);
     736        var otherTime = durationForRecordType();
     737        var idleTime = totalTime - layoutTime - scriptTime - otherTime;
     738
     739        this._frameSelectionChartRow.data = [
     740            {label: WebInspector.UIString("Layout"), value: layoutTime, color: this._chartColors.layout},
     741            {label: WebInspector.UIString("Script"), value: scriptTime, color: this._chartColors.script},
     742            {label: WebInspector.UIString("Other"), value: otherTime, color: this._chartColors.other},
     743            {label: WebInspector.UIString("Idle"), value: idleTime, color: this._chartColors.idle}
     744        ];
    616745    }
    617746
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineTabContentView.js

    r183376 r183721  
    2727{
    2828    var tabBarItem = new WebInspector.TabBarItem("Images/Timeline.svg", WebInspector.UIString("Timelines"));
    29     var detailsSidebarPanels = [WebInspector.resourceDetailsSidebarPanel, WebInspector.probeDetailsSidebarPanel, WebInspector.renderingFrameDetailsSidebarPanel];
     29    var detailsSidebarPanels = [WebInspector.resourceDetailsSidebarPanel, WebInspector.probeDetailsSidebarPanel];
    3030
    3131    // FIME: Until TimelineSidebarPanel supports instantiating after inspector launch, disable closing.
  • trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj

    r183469 r183721  
    298298    <None Include="..\UserInterface\CanvasProfileType.js" />
    299299    <None Include="..\UserInterface\CanvasProfileView.js" />
    300     <None Include="..\UserInterface\ChartDetailsSectionLegendRow.js" />
    301300    <None Include="..\UserInterface\ChartDetailsSectionRow.js" />
    302301    <None Include="..\UserInterface\ChartDetailsSectionRow.css" />
     
    739738    <None Include="..\UserInterface\RadioButtonNavigationItem.js" />
    740739    <None Include="..\UserInterface\RemoteObject.js" />
    741     <None Include="..\UserInterface\RenderingFrameDetailsSidebarPanel.js" />
    742740    <None Include="..\UserInterface\RenderingFrameTimeDataGridNode.js" />
    743741    <None Include="..\UserInterface\RenderingFrameTimelineOverview.js" />
  • trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters

    r183469 r183721  
    142142      <Filter>UserInterface</Filter>
    143143    </None>
    144     <None Include="..\UserInterface\ChartDetailsSectionLegendRow.js">
    145       <Filter>UserInterface</Filter>
    146     </None>
    147144    <None Include="..\UserInterface\ChartDetailsSectionRow.js">
    148145      <Filter>UserInterface</Filter>
     
    782779    </None>
    783780    <None Include="..\UserInterface\RemoteObject.js">
    784       <Filter>UserInterface</Filter>
    785     </None>
    786     <None Include="..\UserInterface\RenderingFrameDetailsSidebarPanel.js">
    787781      <Filter>UserInterface</Filter>
    788782    </None>
Note: See TracChangeset for help on using the changeset viewer.