4daf827e14477d10e682895a1e26f3c7ecf78dff
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Views / NetworkTimelineView.js
1 /*
2  * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 WebInspector.NetworkTimelineView = class NetworkTimelineView extends WebInspector.TimelineView
27 {
28     constructor(timeline, extraArguments)
29     {
30         super(timeline, extraArguments);
31
32         console.assert(timeline.type === WebInspector.TimelineRecord.Type.Network);
33
34         this.navigationSidebarTreeOutline.disclosureButtons = false;
35         this.navigationSidebarTreeOutline.element.classList.add("network");
36
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%";
42
43         columns.domain.title = WebInspector.UIString("Domain");
44         columns.domain.width = "10%";
45
46         columns.type.title = WebInspector.UIString("Type");
47         columns.type.width = "8%";
48
49         var typeToLabelMap = new Map;
50         for (var key in WebInspector.Resource.Type) {
51             var value = WebInspector.Resource.Type[key];
52             typeToLabelMap.set(value, WebInspector.Resource.displayNameForType(value, true));
53         }
54
55         columns.type.scopeBar = WebInspector.TimelineDataGrid.createColumnScopeBar("network", typeToLabelMap);
56         this._scopeBar = columns.type.scopeBar;
57
58         columns.method.title = WebInspector.UIString("Method");
59         columns.method.width = "6%";
60
61         columns.scheme.title = WebInspector.UIString("Scheme");
62         columns.scheme.width = "6%";
63
64         columns.statusCode.title = WebInspector.UIString("Status");
65         columns.statusCode.width = "6%";
66
67         columns.cached.title = WebInspector.UIString("Cached");
68         columns.cached.width = "6%";
69
70         columns.size.title = WebInspector.UIString("Size");
71         columns.size.width = "8%";
72         columns.size.aligned = "right";
73
74         columns.transferSize.title = WebInspector.UIString("Transferred");
75         columns.transferSize.width = "8%";
76         columns.transferSize.aligned = "right";
77
78         columns.requestSent.title = WebInspector.UIString("Start Time");
79         columns.requestSent.width = "9%";
80         columns.requestSent.aligned = "right";
81
82         columns.latency.title = WebInspector.UIString("Latency");
83         columns.latency.width = "9%";
84         columns.latency.aligned = "right";
85
86         columns.duration.title = WebInspector.UIString("Duration");
87         columns.duration.width = "9%";
88         columns.duration.aligned = "right";
89
90         for (var column in columns)
91             columns[column].sortable = true;
92
93         this._dataGrid = new WebInspector.TimelineDataGrid(this.navigationSidebarTreeOutline, columns);
94         this._dataGrid.addEventListener(WebInspector.TimelineDataGrid.Event.FiltersDidChange, this._dataGridFiltersDidChange, this);
95         this._dataGrid.addEventListener(WebInspector.DataGrid.Event.SelectedNodeChanged, this._dataGridNodeSelected, this);
96         this._dataGrid.sortColumnIdentifierSetting = new WebInspector.Setting("network-timeline-view-sort", "requestSent");
97         this._dataGrid.sortOrderSetting = new WebInspector.Setting("network-timeline-view-sort-order", WebInspector.DataGrid.SortOrder.Ascending);
98
99         this.element.classList.add("network");
100         this.addSubview(this._dataGrid);
101
102         timeline.addEventListener(WebInspector.Timeline.Event.RecordAdded, this._networkTimelineRecordAdded, this);
103
104         this._pendingRecords = [];
105     }
106
107     // Public
108
109     get navigationSidebarTreeOutlineLabel()
110     {
111         return WebInspector.UIString("Resources");
112     }
113
114     shown()
115     {
116         super.shown();
117
118         this._dataGrid.shown();
119     }
120
121     hidden()
122     {
123         this._dataGrid.hidden();
124
125         super.hidden();
126     }
127
128     closed()
129     {
130         console.assert(this.representedObject instanceof WebInspector.Timeline);
131         this.representedObject.removeEventListener(null, null, this);
132
133         this._dataGrid.closed();
134     }
135
136     matchTreeElementAgainstCustomFilters(treeElement)
137     {
138         return this._dataGrid.treeElementMatchesActiveScopeFilters(treeElement);
139     }
140
141     reset()
142     {
143         super.reset();
144
145         this._dataGrid.reset();
146
147         this._pendingRecords = [];
148     }
149
150     // Protected
151
152     canShowContentViewForTreeElement(treeElement)
153     {
154         if (treeElement instanceof WebInspector.ResourceTreeElement || treeElement instanceof WebInspector.ScriptTreeElement)
155             return true;
156         return super.canShowContentViewForTreeElement(treeElement);
157     }
158
159     showContentViewForTreeElement(treeElement)
160     {
161         if (treeElement instanceof WebInspector.ResourceTreeElement || treeElement instanceof WebInspector.ScriptTreeElement) {
162             WebInspector.showSourceCode(treeElement.representedObject);
163             return;
164         }
165
166         console.error("Unknown tree element selected.", treeElement);
167     }
168
169     treeElementPathComponentSelected(event)
170     {
171         var dataGridNode = this._dataGrid.dataGridNodeForTreeElement(event.data.pathComponent.generalTreeElement);
172         if (!dataGridNode)
173             return;
174         dataGridNode.revealAndSelect();
175     }
176
177     treeElementSelected(treeElement, selectedByUser)
178     {
179         if (this._dataGrid.shouldIgnoreSelectionEvent())
180             return;
181
182         super.treeElementSelected(treeElement, selectedByUser);
183     }
184
185     layout()
186     {
187         this._processPendingRecords();
188     }
189
190     // Private
191
192     _processPendingRecords()
193     {
194         if (!this._pendingRecords.length)
195             return;
196
197         for (var resourceTimelineRecord of this._pendingRecords) {
198             // Skip the record if it already exists in the tree.
199             var treeElement = this.navigationSidebarTreeOutline.findTreeElement(resourceTimelineRecord.resource);
200             if (treeElement)
201                 continue;
202
203             treeElement = new WebInspector.ResourceTreeElement(resourceTimelineRecord.resource);
204             var dataGridNode = new WebInspector.ResourceTimelineDataGridNode(resourceTimelineRecord, false, this);
205
206             this._dataGrid.addRowInSortOrder(treeElement, dataGridNode);
207         }
208
209         this._pendingRecords = [];
210     }
211
212     _networkTimelineRecordAdded(event)
213     {
214         var resourceTimelineRecord = event.data.record;
215         console.assert(resourceTimelineRecord instanceof WebInspector.ResourceTimelineRecord);
216
217         this._pendingRecords.push(resourceTimelineRecord);
218
219         this.needsLayout();
220     }
221
222     _dataGridFiltersDidChange(event)
223     {
224         this.timelineSidebarPanel.updateFilter();
225     }
226
227     _dataGridNodeSelected(event)
228     {
229         this.dispatchEventToListeners(WebInspector.ContentView.Event.SelectionPathComponentsDidChange);
230     }
231 };