Changeset 197487 in webkit


Ignore:
Timestamp:
Mar 2, 2016 7:45:50 PM (8 years ago)
Author:
Matt Baker
Message:

Web Inspector: Timelines UI redesign: show content tree outline records in timeline data grids
https://bugs.webkit.org/show_bug.cgi?id=153032
<rdar://problem/24195317>

Reviewed by Timothy Hatcher.

This patch relocates the data shown in the Timelines navigation sidebar content tree outline
to a new grid column in each TimelineDataGrid. Logic for creating subtitles, goto arrow buttons,
and status elements (the progress spinner used for network resources) has been replicated in
the appropriate TimelineDataGridNode classes.

Duplicate logic contained in TimelineRecordTreeElement classes is left in place for now, but
will be removed in <https://webkit.org/b/153036>.

  • UserInterface/Views/DataGrid.css:

(.data-grid td.error):
Use --error-text-color CSS variable.

  • UserInterface/Views/DataGrid.js:

Removed GoToArrowClicked event.
(WebInspector.DataGridNode.prototype.createGoToArrowButton.buttonClicked): Deleted.
(WebInspector.DataGridNode.prototype.createGoToArrowButton): Deleted.
Now part of TimelineDataGridNode.

  • UserInterface/Views/LayoutTimelineDataGridNode.js:

(WebInspector.LayoutTimelineDataGridNode):
(WebInspector.LayoutTimelineDataGridNode.prototype.get data):
Add name cell to row data.
(WebInspector.LayoutTimelineDataGridNode.prototype.createCellContent):
Create name cell.

  • UserInterface/Views/LayoutTimelineView.css:

(.timeline-view.layout > .data-grid .eventType-column): Deleted.
Column border no longer hidden.

  • UserInterface/Views/LayoutTimelineView.js:

(WebInspector.LayoutTimelineView):
Setup name column.

  • UserInterface/Views/NetworkTimelineView.css:

(.timeline-view.network > .data-grid .name-column .subtitle):
Don't show subtitles in the Network grid's name column.

  • UserInterface/Views/NetworkTimelineView.js:

(WebInspector.NetworkTimelineView):
Setup name column.

  • UserInterface/Views/OverviewTimelineView.css:

(.timeline-view.overview > .data-grid th.graph-column > .timeline-ruler):
(.timeline-view.overview > .data-grid th.graph-column > .timeline-ruler > .header):
(.timeline-view.overview > .data-grid th):
(body.window-inactive .timeline-view.overview > .data-grid th):
(.timeline-view.overview .timeline-ruler > .event-markers):
(.timeline-view.overview > .data-grid):
(.timeline-view.overview > .timeline-ruler): Deleted.
(.timeline-view.overview > .timeline-ruler > .header): Deleted.
(body.window-inactive .timeline-view.overview > .timeline-ruler > .header): Deleted.
(.timeline-view.overview > .timeline-ruler > .event-markers): Deleted.
New styles for adding grid column headers and using a TimelineRuler as the
graph column header.

  • UserInterface/Views/OverviewTimelineView.js:

(WebInspector.OverviewTimelineView):
Setup name column and add ruler to graph column header.

  • UserInterface/Views/ProfileNodeDataGridNode.js:

(WebInspector.ProfileNodeDataGridNode):
Use cached data instead of creating row data at construction time.
(WebInspector.ProfileNodeDataGridNode.prototype.get data):
Add name cell to row data.
(WebInspector.ProfileNodeDataGridNode.prototype.createCellContent):
Create name cell.
(WebInspector.ProfileNodeDataGridNode.prototype._iconClassNameForProfileNode):
(WebInspector.ProfileNodeDataGridNode.prototype._titleForProfileNode):
Copied from ProfileNodeTreeElement.

  • UserInterface/Views/RenderingFrameTimelineDataGridNode.js:

(WebInspector.RenderingFrameTimelineDataGridNode):
(WebInspector.RenderingFrameTimelineDataGridNode.prototype.get data):
Add name cell to row data.
(WebInspector.RenderingFrameTimelineDataGridNode.prototype.createCellContent):
Create name cell.

  • UserInterface/Views/RenderingFrameTimelineView.js:

(WebInspector.RenderingFrameTimelineView):
Setup name column.

  • UserInterface/Views/ResourceTimelineDataGridNode.js:

(WebInspector.ResourceTimelineDataGridNode):
Renamed "graphOnly" to "includesGraph", since resource rows in the overview
now show the name column in addition to the graph column. Resource events
LoadingDidFinish and LoadingDidFail now need to be handled for both types
of resource rows.

(WebInspector.ResourceTimelineDataGridNode.prototype.get data):
(WebInspector.ResourceTimelineDataGridNode.prototype.createCellContent):
Update resource status element and create name cell content.
(WebInspector.ResourceTimelineDataGridNode.prototype._createNameCellDocumentFragment):
Create DOM fragment with titles. Based on code in TimelineRecordTreeElement.
(WebInspector.ResourceTimelineDataGridNode.prototype._dataGridNodeGoToArrowClicked):
Show resource when goto arrow is clicked.
(WebInspector.ResourceTimelineDataGridNode.prototype._updateStatus):
Update name cell's text color and progress spinner.

  • UserInterface/Views/ResourceTreeElement.css:

(.item.resource.failed):
(.item.resource.failed .subtitle):
Use --error-text-color CSS variable.

  • UserInterface/Views/ScriptTimelineDataGridNode.js:

(WebInspector.ScriptTimelineDataGridNode):
(WebInspector.ScriptTimelineDataGridNode.prototype.createCellContent):
(WebInspector.ScriptTimelineDataGridNode.prototype._createNameCellDocumentFragment):
Create DOM fragment with titles. Based on code in TimelineRecordTreeElement.

  • UserInterface/Views/ScriptTimelineView.js:

(WebInspector.ScriptTimelineView):
Setup name column.

  • UserInterface/Views/SourceCodeTimelineTimelineDataGridNode.js:

(WebInspector.SourceCodeTimelineTimelineDataGridNode.prototype.createCellContent):
Added now that this node type is no longer "graph only".
(WebInspector.SourceCodeTimelineTimelineDataGridNode.prototype._createNameCellContent):
Create DOM fragment with titles. Based on code in TimelineRecordTreeElement.

  • UserInterface/Views/TimelineDataGridNode.js:

(WebInspector.TimelineDataGridNode):
Renamed graphOnly to includesGraph.
(WebInspector.TimelineDataGridNode.prototype.createCellContent):
Removed icon element creation. This is now handled by the DataGrid.
(WebInspector.TimelineDataGridNode.prototype.refresh):
Refresh of all node cells after updating the graph.
(WebInspector.TimelineDataGridNode.prototype.createGoToArrowButton):
(WebInspector.TimelineDataGridNode.prototype.createGoToArrowButton.buttonClicked):
Relocated from DataGrid, as it's only used by TimelineDataGridNodes.

  • UserInterface/Views/TimelineView.css:

(.timeline-view > .data-grid .indeterminate-progress-spinner):
Styles for grid cell progress spinners.

  • UserInterface/Views/Variables.css:

(:root):
Added --error-text-color variable to remove duplication.

Location:
trunk/Source/WebInspectorUI
Files:
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r197479 r197487  
     12016-03-02  Matt Baker  <mattbaker@apple.com>
     2
     3        Web Inspector: Timelines UI redesign: show content tree outline records in timeline data grids
     4        https://bugs.webkit.org/show_bug.cgi?id=153032
     5        <rdar://problem/24195317>
     6
     7        Reviewed by Timothy Hatcher.
     8
     9        This patch relocates the data shown in the Timelines navigation sidebar content tree outline
     10        to a new grid column in each TimelineDataGrid. Logic for creating subtitles, goto arrow buttons,
     11        and status elements (the progress spinner used for network resources) has been replicated in
     12        the appropriate TimelineDataGridNode classes.
     13
     14        Duplicate logic contained in TimelineRecordTreeElement classes is left in place for now, but
     15        will be removed in <https://webkit.org/b/153036>.
     16
     17        * UserInterface/Views/DataGrid.css:
     18        (.data-grid td.error):
     19        Use --error-text-color CSS variable.
     20
     21        * UserInterface/Views/DataGrid.js:
     22        Removed GoToArrowClicked event.
     23        (WebInspector.DataGridNode.prototype.createGoToArrowButton.buttonClicked): Deleted.
     24        (WebInspector.DataGridNode.prototype.createGoToArrowButton): Deleted.
     25        Now part of TimelineDataGridNode.
     26
     27        * UserInterface/Views/LayoutTimelineDataGridNode.js:
     28        (WebInspector.LayoutTimelineDataGridNode):
     29        (WebInspector.LayoutTimelineDataGridNode.prototype.get data):
     30        Add name cell to row data.
     31        (WebInspector.LayoutTimelineDataGridNode.prototype.createCellContent):
     32        Create name cell.
     33
     34        * UserInterface/Views/LayoutTimelineView.css:
     35        (.timeline-view.layout > .data-grid .eventType-column): Deleted.
     36        Column border no longer hidden.
     37
     38        * UserInterface/Views/LayoutTimelineView.js:
     39        (WebInspector.LayoutTimelineView):
     40        Setup name column.
     41
     42        * UserInterface/Views/NetworkTimelineView.css:
     43        (.timeline-view.network > .data-grid .name-column .subtitle):
     44        Don't show subtitles in the Network grid's name column.
     45
     46        * UserInterface/Views/NetworkTimelineView.js:
     47        (WebInspector.NetworkTimelineView):
     48        Setup name column.
     49
     50        * UserInterface/Views/OverviewTimelineView.css:
     51        (.timeline-view.overview > .data-grid th.graph-column > .timeline-ruler):
     52        (.timeline-view.overview > .data-grid th.graph-column > .timeline-ruler > .header):
     53        (.timeline-view.overview > .data-grid th):
     54        (body.window-inactive .timeline-view.overview > .data-grid th):
     55        (.timeline-view.overview .timeline-ruler > .event-markers):
     56        (.timeline-view.overview > .data-grid):
     57        (.timeline-view.overview > .timeline-ruler): Deleted.
     58        (.timeline-view.overview > .timeline-ruler > .header): Deleted.
     59        (body.window-inactive .timeline-view.overview > .timeline-ruler > .header): Deleted.
     60        (.timeline-view.overview > .timeline-ruler > .event-markers): Deleted.
     61        New styles for adding grid column headers and using a TimelineRuler as the
     62        graph column header.
     63
     64        * UserInterface/Views/OverviewTimelineView.js:
     65        (WebInspector.OverviewTimelineView):
     66        Setup name column and add ruler to graph column header.
     67
     68        * UserInterface/Views/ProfileNodeDataGridNode.js:
     69        (WebInspector.ProfileNodeDataGridNode):
     70        Use cached data instead of creating row data at construction time.
     71        (WebInspector.ProfileNodeDataGridNode.prototype.get data):
     72        Add name cell to row data.
     73        (WebInspector.ProfileNodeDataGridNode.prototype.createCellContent):
     74        Create name cell.
     75        (WebInspector.ProfileNodeDataGridNode.prototype._iconClassNameForProfileNode):
     76        (WebInspector.ProfileNodeDataGridNode.prototype._titleForProfileNode):
     77        Copied from ProfileNodeTreeElement.
     78
     79        * UserInterface/Views/RenderingFrameTimelineDataGridNode.js:
     80        (WebInspector.RenderingFrameTimelineDataGridNode):
     81        (WebInspector.RenderingFrameTimelineDataGridNode.prototype.get data):
     82        Add name cell to row data.
     83        (WebInspector.RenderingFrameTimelineDataGridNode.prototype.createCellContent):
     84        Create name cell.
     85
     86        * UserInterface/Views/RenderingFrameTimelineView.js:
     87        (WebInspector.RenderingFrameTimelineView):
     88        Setup name column.
     89
     90        * UserInterface/Views/ResourceTimelineDataGridNode.js:
     91        (WebInspector.ResourceTimelineDataGridNode):
     92        Renamed "graphOnly" to "includesGraph", since resource rows in the overview
     93        now show the name column in addition to the graph column. Resource events
     94        LoadingDidFinish and LoadingDidFail now need to be handled for both types
     95        of resource rows.
     96
     97        (WebInspector.ResourceTimelineDataGridNode.prototype.get data):
     98        (WebInspector.ResourceTimelineDataGridNode.prototype.createCellContent):
     99        Update resource status element and create name cell content.
     100        (WebInspector.ResourceTimelineDataGridNode.prototype._createNameCellDocumentFragment):
     101        Create DOM fragment with titles. Based on code in TimelineRecordTreeElement.
     102        (WebInspector.ResourceTimelineDataGridNode.prototype._dataGridNodeGoToArrowClicked):
     103        Show resource when goto arrow is clicked.
     104        (WebInspector.ResourceTimelineDataGridNode.prototype._updateStatus):
     105        Update name cell's text color and progress spinner.
     106
     107        * UserInterface/Views/ResourceTreeElement.css:
     108        (.item.resource.failed):
     109        (.item.resource.failed .subtitle):
     110        Use --error-text-color CSS variable.
     111
     112        * UserInterface/Views/ScriptTimelineDataGridNode.js:
     113        (WebInspector.ScriptTimelineDataGridNode):
     114        (WebInspector.ScriptTimelineDataGridNode.prototype.createCellContent):
     115        (WebInspector.ScriptTimelineDataGridNode.prototype._createNameCellDocumentFragment):
     116        Create DOM fragment with titles. Based on code in TimelineRecordTreeElement.
     117
     118        * UserInterface/Views/ScriptTimelineView.js:
     119        (WebInspector.ScriptTimelineView):
     120        Setup name column.
     121
     122        * UserInterface/Views/SourceCodeTimelineTimelineDataGridNode.js:
     123        (WebInspector.SourceCodeTimelineTimelineDataGridNode.prototype.createCellContent):
     124        Added now that this node type is no longer "graph only".
     125        (WebInspector.SourceCodeTimelineTimelineDataGridNode.prototype._createNameCellContent):
     126        Create DOM fragment with titles. Based on code in TimelineRecordTreeElement.
     127
     128        * UserInterface/Views/TimelineDataGridNode.js:
     129        (WebInspector.TimelineDataGridNode):
     130        Renamed `graphOnly` to `includesGraph`.
     131        (WebInspector.TimelineDataGridNode.prototype.createCellContent):
     132        Removed icon element creation. This is now handled by the DataGrid.
     133        (WebInspector.TimelineDataGridNode.prototype.refresh):
     134        Refresh of all node cells after updating the graph.
     135        (WebInspector.TimelineDataGridNode.prototype.createGoToArrowButton):
     136        (WebInspector.TimelineDataGridNode.prototype.createGoToArrowButton.buttonClicked):
     137        Relocated from DataGrid, as it's only used by TimelineDataGridNodes.
     138
     139        * UserInterface/Views/TimelineView.css:
     140        (.timeline-view > .data-grid .indeterminate-progress-spinner):
     141        Styles for grid cell progress spinners.
     142
     143        * UserInterface/Views/Variables.css:
     144        (:root):
     145        Added --error-text-color variable to remove duplication.
     146
    11472016-03-02  Matt Baker  <mattbaker@apple.com>
    2148
  • trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.css

    r197265 r197487  
    265265
    266266.data-grid td.error {
    267     color: hsl(0, 86%, 47%);
     267    color: var(--error-text-color);
    268268}
    269269
  • trunk/Source/WebInspectorUI/UserInterface/Views/DataGrid.js

    r196549 r197487  
    13981398    SelectedNodeChanged: "datagrid-selected-node-changed",
    13991399    ExpandedNode: "datagrid-expanded-node",
    1400     CollapsedNode: "datagrid-collapsed-node",
    1401     GoToArrowClicked: "datagrid-go-to-arrow-clicked"
     1400    CollapsedNode: "datagrid-collapsed-node"
    14021401};
    14031402
     
    15091508    }
    15101509
    1511     createGoToArrowButton(cellElement)
    1512     {
    1513         function buttonClicked(event)
    1514         {
    1515             if (this.hidden || !this.revealed)
    1516                 return;
    1517 
    1518             event.stopPropagation();
    1519 
    1520             let columnIdentifier = cellElement.__columnIdentifier;
    1521             this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Event.GoToArrowClicked, {dataGridNode: this, columnIdentifier});
    1522         }
    1523 
    1524         let button = WebInspector.createGoToArrowButton();
    1525         button.addEventListener("click", buttonClicked.bind(this));
    1526 
    1527         let contentElement = cellElement.firstChild;
    1528         contentElement.appendChild(button);
    1529     }
    1530 
    15311510    refreshIfNeeded()
    15321511    {
  • trunk/Source/WebInspectorUI/UserInterface/Views/LayoutTimelineDataGridNode.js

    r196275 r197487  
    5050        if (!this._cachedData) {
    5151            this._cachedData = {
    52                 eventType: this._record.eventType,
     52                name: WebInspector.LayoutTimelineRecord.displayNameForEventType(this._record.eventType),
    5353                width: this._record.width,
    5454                height: this._record.height,
     
    6868
    6969        switch (columnIdentifier) {
    70         case "eventType":
    71             return WebInspector.LayoutTimelineRecord.displayNameForEventType(value);
     70        case "name":
     71            cell.classList.add(WebInspector.TimelineTabContentView.iconClassNameForRecord(this._record));
     72            return value;
    7273
    7374        case "width":
  • trunk/Source/WebInspectorUI/UserInterface/Views/LayoutTimelineView.css

    r195303 r197487  
    3232}
    3333
    34 .timeline-view.layout > .data-grid .eventType-column {
    35     border-right: none;
    36 }
    37 
    3834.sidebar > .panel.navigation.timeline.timeline-recording-content-view-showing .tree-outline.layout .item .subtitle {
    3935    display: none;
  • trunk/Source/WebInspectorUI/UserInterface/Views/LayoutTimelineView.js

    r194878 r197487  
    3434        this.navigationSidebarTreeOutline.element.classList.add("layout");
    3535
    36         var columns = {eventType: {}, location: {}, width: {}, height: {}, startTime: {}, totalTime: {}};
    37 
    38         columns.eventType.title = WebInspector.UIString("Type");
    39         columns.eventType.width = "15%";
     36        let columns = {name: {}, location: {}, width: {}, height: {}, startTime: {}, totalTime: {}};
     37
     38        columns.name.title = WebInspector.UIString("Type");
     39        columns.name.width = "15%";
    4040
    4141        var typeToLabelMap = new Map;
     
    4545        }
    4646
    47         columns.eventType.scopeBar = WebInspector.TimelineDataGrid.createColumnScopeBar("layout", typeToLabelMap);
    48         columns.eventType.hidden = true;
    49         this._scopeBar = columns.eventType.scopeBar;
     47        columns.name.scopeBar = WebInspector.TimelineDataGrid.createColumnScopeBar("layout", typeToLabelMap);
     48        columns.name.disclosure = true;
     49        columns.name.icon = true;
     50
     51        this._scopeBar = columns.name.scopeBar;
    5052
    5153        columns.location.title = WebInspector.UIString("Initiator");
  • trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTimelineView.css

    r195303 r197487  
    3232}
    3333
     34.timeline-view.network > .data-grid .name-column .subtitle {
     35    display: none;
     36}
     37
    3438.sidebar > .panel.navigation.timeline.timeline-recording-content-view-showing .tree-outline.network .item .subtitle {
    3539    display: none;
  • trunk/Source/WebInspectorUI/UserInterface/Views/NetworkTimelineView.js

    r195303 r197487  
    3535        this.navigationSidebarTreeOutline.element.classList.add("network");
    3636
    37         var columns = {domain: {}, type: {}, method: {}, scheme: {}, statusCode: {}, cached: {}, size: {}, transferSize: {}, requestSent: {}, latency: {}, duration: {}};
     37        let columns = {name: {}, domain: {}, type: {}, method: {}, scheme: {}, statusCode: {}, cached: {}, size: {}, transferSize: {}, requestSent: {}, latency: {}, duration: {}};
     38
     39        columns.name.title = WebInspector.UIString("Name");
     40        columns.name.icon = true;
     41        columns.name.width = "10%";
    3842
    3943        columns.domain.title = WebInspector.UIString("Domain");
  • trunk/Source/WebInspectorUI/UserInterface/Views/OverviewTimelineView.css

    r197473 r197487  
    2424 */
    2525
    26 .timeline-view.overview > .timeline-ruler {
     26.timeline-view.overview > .data-grid th.graph-column > .timeline-ruler {
     27    position: absolute;
     28    top: 0;
     29    bottom: 0;
     30}
     31
     32.timeline-view.overview > .data-grid th.graph-column > .timeline-ruler > .header {
     33    border: none;
     34    height: 22px;
     35}
     36
     37.timeline-view.overview > .data-grid th.graph-column > .timeline-ruler > .event-markers {
     38    top: 22px;
     39}
     40
     41.timeline-view.overview > .data-grid {
    2742    position: absolute;
    2843    top: 0;
     
    3247}
    3348
    34 .timeline-view.overview > .timeline-ruler > .header {
    35     border-top: 1px solid var(--border-color);
    36     height: 23px;
    37 }
    38 
    39 .timeline-view.overview > .timeline-ruler > .event-markers {
    40     top: 23px;
    41     border-top: 1px solid var(--border-color);
    42 }
    43 
    44 .timeline-view.overview > .data-grid {
    45     position: absolute;
    46     top: 23px;
    47     left: 0;
    48     right: 0;
    49     bottom: 0;
     49.timeline-view.overview > .data-grid th {
     50    border-top: solid 1px var(--border-color);
    5051}
    5152
  • trunk/Source/WebInspectorUI/UserInterface/Views/OverviewTimelineView.js

    r195995 r197487  
    3232        this._recording = recording;
    3333
    34         var columns = {"graph": {width: "100%"}};
     34        let columns = {name: {}, graph: {}};
     35
     36        columns.name.title = WebInspector.UIString("Name");
     37        columns.name.width = "20%";
     38        columns.name.icon = true;
     39        columns.name.disclosure = true;
     40
     41        this._timelineRuler = new WebInspector.TimelineRuler;
     42        this._timelineRuler.allowsClippedLabels = true;
     43
     44        columns.graph.width = "80%";
     45        columns.graph.headerView = this._timelineRuler;
    3546
    3647        this._dataGrid = new WebInspector.DataGrid(columns);
    3748        this._dataGrid.addEventListener(WebInspector.DataGrid.Event.SelectedNodeChanged, this._dataGridNodeSelected, this);
    38         this._dataGrid.element.classList.add("no-header");
    3949
    4050        this._treeOutlineDataGridSynchronizer = new WebInspector.TreeOutlineDataGridSynchronizer(this.navigationSidebarTreeOutline, this._dataGrid);
    41 
    42         this._timelineRuler = new WebInspector.TimelineRuler;
    43         this._timelineRuler.allowsClippedLabels = true;
    44         this.addSubview(this._timelineRuler);
    4551
    4652        this._currentTimeMarker = new WebInspector.TimelineMarker(0, WebInspector.TimelineMarker.Type.CurrentTime);
  • trunk/Source/WebInspectorUI/UserInterface/Views/ProfileNodeDataGridNode.js

    r196275 r197487  
    3737        this._rangeEndTime = typeof rangeEndTime === "number" ? rangeEndTime : Infinity;
    3838
    39         this._data = this._profileNode.computeCallInfoForTimeRange(this._rangeStartTime, this._rangeEndTime);
    40         this._data.location = this._profileNode.sourceCodeLocation;
     39        this._cachedData = null;
    4140    }
    4241
     
    7069    get data()
    7170    {
    72         return this._data;
     71        if (!this._cachedData) {
     72            this._cachedData = this._profileNode.computeCallInfoForTimeRange(this._rangeStartTime, this._rangeEndTime);
     73            this._cachedData.name = this._titleForProfileNode();
     74            this._cachedData.location = this._profileNode.sourceCodeLocation;
     75        }
     76
     77        return this._cachedData;
    7378    }
    7479
     
    109114
    110115        switch (columnIdentifier) {
     116        case "name":
     117            cell.classList.add(this._iconClassNameForProfileNode());
     118            return value;
     119
    111120        case "startTime":
    112121            return isNaN(value) ? emDash : Number.secondsToString(value - this._baseStartTime, true);
     
    120129        return super.createCellContent(columnIdentifier, cell);
    121130    }
     131
     132    // Private
     133
     134    _iconClassNameForProfileNode()
     135    {
     136        let className;
     137        switch (this._profileNode.type) {
     138        case WebInspector.ProfileNode.Type.Function:
     139            className = WebInspector.CallFrameView.FunctionIconStyleClassName;
     140            if (!this._profileNode.sourceCodeLocation)
     141                className = WebInspector.CallFrameView.NativeIconStyleClassName;
     142            break;
     143        case WebInspector.ProfileNode.Type.Program:
     144            className = WebInspector.TimelineRecordTreeElement.EvaluatedRecordIconStyleClass;
     145            break;
     146        }
     147
     148        console.assert(className);
     149
     150        // This is more than likely an event listener function with an "on" prefix and it is
     151        // as long or longer than the shortest event listener name -- "oncut".
     152        if (this._profileNode.functionName && this._profileNode.functionName.startsWith("on") && this._profileNode.functionName.length >= 5)
     153            className = WebInspector.CallFrameView.EventListenerIconStyleClassName;
     154
     155        return className;
     156    }
     157
     158    _titleForProfileNode()
     159    {
     160        let title = this._profileNode.functionName;
     161        if (!name) {
     162            switch (this._profileNode.type) {
     163            case WebInspector.ProfileNode.Type.Function:
     164                title = WebInspector.UIString("(anonymous function)");
     165                break;
     166            case WebInspector.ProfileNode.Type.Program:
     167                title = WebInspector.UIString("(program)");
     168                break;
     169            default:
     170                title = WebInspector.UIString("(anonymous function)");
     171                console.error("Unknown ProfileNode type: " + this._profileNode.type);
     172            }
     173        }
     174
     175        return title;
     176    }
    122177};
  • trunk/Source/WebInspectorUI/UserInterface/Views/RenderingFrameTimelineDataGridNode.js

    r196275 r197487  
    4949    {
    5050        if (!this._cachedData) {
    51             var scriptTime = this._record.durationForTask(WebInspector.RenderingFrameTimelineRecord.TaskType.Script);
    52             var layoutTime = this._record.durationForTask(WebInspector.RenderingFrameTimelineRecord.TaskType.Layout);
    53             var paintTime = this._record.durationForTask(WebInspector.RenderingFrameTimelineRecord.TaskType.Paint);
    54             var otherTime = this._record.durationForTask(WebInspector.RenderingFrameTimelineRecord.TaskType.Other);
     51            let name = WebInspector.TimelineTabContentView.displayNameForRecord(this._record);
     52            let scriptTime = this._record.durationForTask(WebInspector.RenderingFrameTimelineRecord.TaskType.Script);
     53            let layoutTime = this._record.durationForTask(WebInspector.RenderingFrameTimelineRecord.TaskType.Layout);
     54            let paintTime = this._record.durationForTask(WebInspector.RenderingFrameTimelineRecord.TaskType.Paint);
     55            let otherTime = this._record.durationForTask(WebInspector.RenderingFrameTimelineRecord.TaskType.Other);
    5556            this._cachedData = {
     57                name,
    5658                startTime: this._record.startTime,
    5759                totalTime: this._record.duration,
     
    7173
    7274        switch (columnIdentifier) {
     75        case "name":
     76            cell.classList.add(WebInspector.TimelineTabContentView.iconClassNameForRecord(this._record));
     77            return value;
     78
    7379        case "startTime":
    7480            return isNaN(value) ? emDash : Number.secondsToString(value - this._baseStartTime, true);
  • trunk/Source/WebInspectorUI/UserInterface/Views/RenderingFrameTimelineView.js

    r194878 r197487  
    4343        this._scopeBar.addEventListener(WebInspector.ScopeBar.Event.SelectionChanged, this._scopeBarSelectionDidChange, this);
    4444
    45         let columns = {totalTime: {}, scriptTime: {}, layoutTime: {}, paintTime: {}, otherTime: {}, startTime: {}, location: {}};
     45        let columns = {name: {}, totalTime: {}, scriptTime: {}, layoutTime: {}, paintTime: {}, otherTime: {}, startTime: {}, location: {}};
     46
     47        columns.name.title = WebInspector.UIString("Name");
     48        columns.name.width = "20%";
     49        columns.name.icon = true;
     50        columns.name.disclosure = true;
    4651
    4752        columns.totalTime.title = WebInspector.UIString("Total Time");
  • trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTimelineDataGridNode.js

    r196275 r197487  
    2626WebInspector.ResourceTimelineDataGridNode = class ResourceTimelineDataGridNode extends WebInspector.TimelineDataGridNode
    2727{
    28     constructor(resourceTimelineRecord, graphOnly, graphDataSource)
    29     {
    30         super(graphOnly, graphDataSource);
     28    constructor(resourceTimelineRecord, includesGraph, graphDataSource)
     29    {
     30        super(includesGraph, graphDataSource);
    3131
    3232        this._resource = resourceTimelineRecord.resource;
    3333        this._record = resourceTimelineRecord;
    3434
    35         this._record.addEventListener(WebInspector.TimelineRecord.Event.Updated, graphOnly ? this._timelineRecordUpdated : this._needsRefresh, this);
    36 
    37         if (!graphOnly) {
    38             this._resource.addEventListener(WebInspector.Resource.Event.URLDidChange, this._needsRefresh, this);
     35        this._resource.addEventListener(WebInspector.Resource.Event.LoadingDidFinish, this._needsRefresh, this);
     36        this._resource.addEventListener(WebInspector.Resource.Event.LoadingDidFail, this._needsRefresh, this);
     37        this._resource.addEventListener(WebInspector.Resource.Event.URLDidChange, this._needsRefresh, this);
     38
     39        if (includesGraph)
     40            this._record.addEventListener(WebInspector.TimelineRecord.Event.Updated, this._timelineRecordUpdated, this);
     41        else {
    3942            this._resource.addEventListener(WebInspector.Resource.Event.TypeDidChange, this._needsRefresh, this);
    40             this._resource.addEventListener(WebInspector.Resource.Event.LoadingDidFinish, this._needsRefresh, this);
    41             this._resource.addEventListener(WebInspector.Resource.Event.LoadingDidFail, this._needsRefresh, this);
    4243            this._resource.addEventListener(WebInspector.Resource.Event.SizeDidChange, this._needsRefresh, this);
    4344            this._resource.addEventListener(WebInspector.Resource.Event.TransferSizeDidChange, this._needsRefresh, this);
     
    6566        var data = {};
    6667
    67         if (!this._graphOnly) {
     68        if (!this._includesGraph) {
    6869            var zeroTime = this.graphDataSource ? this.graphDataSource.zeroTime : 0;
    6970
     
    9798
    9899        switch (columnIdentifier) {
     100        case "name":
     101            cell.classList.add(WebInspector.ResourceTreeElement.ResourceIconStyleClassName, resource.type);
     102            cell.title = resource.displayURL;
     103            this._updateStatus(cell);
     104            return this._createNameCellDocumentFragment();
     105
    99106        case "type":
    100107            return WebInspector.Resource.displayNameForType(value);
     
    137144    // Private
    138145
     146    _createNameCellDocumentFragment()
     147    {
     148        let fragment = document.createDocumentFragment();
     149        let mainTitle = WebInspector.TimelineTabContentView.displayNameForRecord(this._record);
     150        fragment.append(mainTitle);
     151
     152        // Show the host as the subtitle if it is different from the main resource or if this is the main frame's main resource.
     153        let frame = this._resource.parentFrame;
     154        let isMainResource = this._resource.isMainResource();
     155        let parentResourceHost;
     156        if (frame && isMainResource) {
     157            // When the resource is a main resource, get the host from the current frame's parent frame instead of the current frame.
     158            parentResourceHost = frame.parentFrame ? frame.parentFrame.mainResource.urlComponents.host : null;
     159        } else if (frame) {
     160            // When the resource is a normal sub-resource, get the host from the current frame's main resource.
     161            parentResourceHost = frame.mainResource.urlComponents.host;
     162        }
     163
     164        if (parentResourceHost !== this._resource.urlComponents.host || frame.isMainFrame() && isMainResource) {
     165            let subtitle = WebInspector.displayNameForHost(this._resource.urlComponents.host);
     166            if (mainTitle !== subtitle) {
     167                let subtitleElement = document.createElement("span");
     168                subtitleElement.classList.add("subtitle");
     169                subtitleElement.textContent = subtitle;
     170                fragment.append(subtitleElement);
     171            }
     172        }
     173
     174        return fragment;
     175    }
     176
    139177    _needsRefresh()
    140178    {
     
    155193            this.needsGraphRefresh();
    156194    }
     195
     196    _dataGridNodeGoToArrowClicked()
     197    {
     198        WebInspector.showSourceCode(this._resource);
     199    }
     200
     201    _updateStatus(cell)
     202    {
     203        if (this._resource.failed)
     204            cell.classList.add("error");
     205        else {
     206            cell.classList.remove("error");
     207
     208            if (this._resource.finished)
     209                this.createGoToArrowButton(cell, this._dataGridNodeGoToArrowClicked.bind(this));
     210        }
     211
     212        if (this._spinner)
     213            this._spinner.element.remove();
     214
     215        if (this._resource.finished || this._resource.failed)
     216            return;
     217
     218        if (!this._spinner)
     219            this._spinner = new WebInspector.IndeterminateProgressSpinner;
     220
     221        let contentElement = cell.firstChild;
     222        contentElement.appendChild(this._spinner.element);
     223    }
    157224};
  • trunk/Source/WebInspectorUI/UserInterface/Views/ResourceTreeElement.css

    r187105 r197487  
    2525
    2626.item.resource.failed {
    27     color: hsl(0, 86%, 47%) !important;
     27    color: var(--error-text-color) !important;
    2828}
    2929
    3030.item.resource.failed .subtitle {
    31     color: hsla(0, 86%, 47%, 0.7) !important;
     31    color: var(--error-text-color) !important;
     32    opacity: 0.7;
    3233}
  • trunk/Source/WebInspectorUI/UserInterface/Views/ScriptTimelineDataGridNode.js

    r196275 r197487  
    125125
    126126        switch (columnIdentifier) {
    127         case "eventType":
    128             return WebInspector.ScriptTimelineRecord.EventType.displayName(value, this._record.details);
     127        case "name":
     128            cell.classList.add(WebInspector.TimelineTabContentView.iconClassNameForRecord(this._record));
     129            return this._createNameCellDocumentFragment();
    129130
    130131        case "startTime":
     
    142143        return super.createCellContent(columnIdentifier, cell);
    143144    }
     145
     146    // Private
     147
     148    _createNameCellDocumentFragment(cellElement)
     149    {
     150        let fragment = document.createDocumentFragment();
     151        let mainTitle = WebInspector.TimelineTabContentView.displayNameForRecord(this._record);
     152        fragment.append(mainTitle);
     153
     154        if (this._record.eventType === WebInspector.ScriptTimelineRecord.EventType.TimerInstalled) {
     155            let subtitleElement = document.createElement("span");
     156            subtitleElement.classList.add("subtitle");
     157            fragment.append(subtitleElement);
     158
     159            let timeoutString = Number.secondsToString(this._record.details.timeout / 1000);
     160            if (this._record.details.repeating)
     161                subtitleElement.textContent = WebInspector.UIString("%s interval").format(timeoutString);
     162            else
     163                subtitleElement.textContent = WebInspector.UIString("%s delay").format(timeoutString);
     164        }
     165
     166        return fragment;
     167    }
    144168};
  • trunk/Source/WebInspectorUI/UserInterface/Views/ScriptTimelineView.js

    r195376 r197487  
    3434        this.navigationSidebarTreeOutline.element.classList.add("script");
    3535
    36         var columns = {location: {}, callCount: {}, startTime: {}, totalTime: {}, selfTime: {}, averageTime: {}};
     36        let columns = {name: {}, location: {}, callCount: {}, startTime: {}, totalTime: {}, selfTime: {}, averageTime: {}};
     37
     38        columns.name.title = WebInspector.UIString("Name");
     39        columns.name.width = "10%";
     40        columns.name.icon = true;
     41        columns.name.disclosure = true;
    3742
    3843        columns.location.title = WebInspector.UIString("Location");
     44        columns.location.icon = true;
    3945        columns.location.width = "15%";
    4046
  • trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTimelineTimelineDataGridNode.js

    r187873 r197487  
    5151    }
    5252
     53    createCellContent(columnIdentifier, cell)
     54    {
     55        if (columnIdentifier === "name" && this.records.length) {
     56            cell.classList.add(WebInspector.TimelineTabContentView.iconClassNameForRecord(this.records[0]));
     57            return this._createNameCellContent(cell);
     58        }
     59
     60        return super.createCellContent(columnIdentifier, cell);
     61    }
     62
    5363    // Private
     64
     65    _createNameCellContent(cellElement)
     66    {
     67        if (!this.records.length)
     68            return null;
     69
     70        let fragment = document.createDocumentFragment();
     71        let mainTitle = WebInspector.TimelineTabContentView.displayNameForRecord(this.records[0]);
     72        fragment.append(mainTitle);
     73
     74        let sourceCodeLocation = this._sourceCodeTimeline.sourceCodeLocation;
     75        if (sourceCodeLocation) {
     76            let subtitleElement = document.createElement("span");
     77            subtitleElement.classList.add("subtitle");
     78            sourceCodeLocation.populateLiveDisplayLocationString(subtitleElement, "textContent", null, WebInspector.SourceCodeLocation.NameStyle.None, WebInspector.UIString("line "));
     79
     80            let goToArrowButtonLink = WebInspector.createSourceCodeLocationLink(sourceCodeLocation, false, true);
     81            fragment.append(goToArrowButtonLink, subtitleElement);
     82
     83            // Give the whole cell a tooltip and keep it up to date.
     84            sourceCodeLocation.populateLiveDisplayLocationTooltip(cellElement, mainTitle + "\n");
     85        } else
     86            cellElement.title = mainTitle;
     87
     88        return fragment;
     89    }
    5490
    5591    _timelineRecordAdded(event)
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineDataGridNode.js

    r196275 r197487  
    2626WebInspector.TimelineDataGridNode = class TimelineDataGridNode extends WebInspector.DataGridNode
    2727{
    28     constructor(graphOnly, graphDataSource, hasChildren)
     28    constructor(includesGraph, graphDataSource, hasChildren)
    2929    {
    3030        super({}, hasChildren);
     
    3232        this.copyable = false;
    3333
    34         this._graphOnly = graphOnly || false;
     34        this._includesGraph = includesGraph || false;
    3535        this._graphDataSource = graphDataSource || null;
    3636
     
    125125            fragment.appendChild(goToArrowButtonLink);
    126126
    127             var icon = document.createElement("div");
    128             icon.className = "icon";
    129             fragment.appendChild(icon);
    130 
    131127            var titleElement = document.createElement("span");
    132128            value.populateLiveDisplayLocationString(titleElement, "textContent");
     
    156152                var goToArrowButtonLink = WebInspector.createSourceCodeLocationLink(callFrame.sourceCodeLocation, false, true);
    157153                fragment.appendChild(goToArrowButtonLink);
    158 
    159                 var icon = document.createElement("div");
    160                 icon.classList.add("icon");
    161                 fragment.appendChild(icon);
    162154
    163155                if (isAnonymousFunction) {
     
    208200    refresh()
    209201    {
    210         if (this._graphDataSource && this._graphOnly) {
     202        if (this._graphDataSource && this._includesGraph)
    211203            this.needsGraphRefresh();
    212             return;
    213         }
    214204
    215205        super.refresh();
     
    321311    // Protected
    322312
     313    createGoToArrowButton(cellElement, callback)
     314    {
     315        function buttonClicked(event)
     316        {
     317            if (this.hidden || !this.revealed)
     318                return;
     319
     320            event.stopPropagation();
     321
     322            callback(this, cellElement.__columnIdentifier);
     323        }
     324
     325        let button = WebInspector.createGoToArrowButton();
     326        button.addEventListener("click", buttonClicked.bind(this));
     327
     328        let contentElement = cellElement.firstChild;
     329        contentElement.appendChild(button);
     330    }
     331
    323332    isRecordVisible(record)
    324333    {
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineView.css

    r195303 r197487  
    3232}
    3333
     34.timeline-view > .data-grid .indeterminate-progress-spinner {
     35    float: right;
     36    margin-left: 2px;
     37}
     38
    3439.panel.navigation.timeline > .content > .tree-outline {
    3540    min-height: 100%;
  • trunk/Source/WebInspectorUI/UserInterface/Views/Variables.css

    r197029 r197487  
    5050    --console-prompt-min-height: 30px;
    5151
     52    --error-text-color: hsl(0, 86%, 47%);
     53
    5254    --syntax-highlight-number-color: hsl(248, 100%, 40%);
    5355    --syntax-highlight-boolean-color: hsl(309, 85%, 35%);
Note: See TracChangeset for help on using the changeset viewer.