Web Inspector: Add a dedicated Network tab that is always live
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / Models / Timeline.js
1 /*
2  * Copyright (C) 2013 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.Timeline = class Timeline extends WebInspector.Object
27 {
28     constructor(type, recording)
29     {
30         super();
31
32         this._type = type;
33         this._recording = recording;
34
35         this.reset(true);
36     }
37
38     // Static
39
40     static create(type, recording)
41     {
42         if (type === WebInspector.TimelineRecord.Type.Network)
43             return new WebInspector.NetworkTimeline(type, recording);
44
45         return new WebInspector.Timeline(type, recording);
46     }
47
48     // Public
49
50     get startTime()
51     {
52         return this._startTime;
53     }
54
55     get endTime()
56     {
57         return this._endTime;
58     }
59
60     get records()
61     {
62         return this._records;
63     }
64
65     get type()
66     {
67         return this._type;
68     }
69
70     get recording()
71     {
72         return this._recording;
73     }
74
75     get displayName()
76     {
77         if (this._type === WebInspector.TimelineRecord.Type.Network)
78             return WebInspector.UIString("Network Requests");
79         if (this._type === WebInspector.TimelineRecord.Type.Layout)
80             return WebInspector.UIString("Layout & Rendering");
81         if (this._type === WebInspector.TimelineRecord.Type.Script)
82             return WebInspector.UIString("JavaScript & Events");
83         if (this._type === WebInspector.TimelineRecord.Type.RenderingFrame)
84             return WebInspector.UIString("Rendering Frames");
85
86         console.error("Timeline has unknown type:", this._type, this);
87     }
88
89     get iconClassName()
90     {
91         if (this._type === WebInspector.TimelineRecord.Type.Network)
92             return WebInspector.TimelineSidebarPanel.NetworkIconStyleClass;
93         if (this._type === WebInspector.TimelineRecord.Type.Layout)
94             return WebInspector.TimelineSidebarPanel.ColorsIconStyleClass;
95         if (this._type === WebInspector.TimelineRecord.Type.Script)
96             return WebInspector.TimelineSidebarPanel.ScriptIconStyleClass;
97         if (this._type === WebInspector.TimelineRecord.Type.RenderingFrame)
98             return WebInspector.TimelineSidebarPanel.RenderingFrameIconStyleClass;
99
100         console.error("Timeline has unknown type:", this._type, this);
101     }
102
103     reset(suppressEvents)
104     {
105         this._records = [];
106         this._startTime = NaN;
107         this._endTime = NaN;
108
109         if (!suppressEvents) {
110             this.dispatchEventToListeners(WebInspector.Timeline.Event.TimesUpdated);
111             this.dispatchEventToListeners(WebInspector.Timeline.Event.Reset);
112         }
113     }
114
115     addRecord(record)
116     {
117         if (record.updatesDynamically)
118             record.addEventListener(WebInspector.TimelineRecord.Event.Updated, this._recordUpdated, this);
119
120         this._records.push(record);
121
122         this._updateTimesIfNeeded(record);
123
124         this.dispatchEventToListeners(WebInspector.Timeline.Event.RecordAdded, {record});
125     }
126
127     saveIdentityToCookie(cookie)
128     {
129         cookie[WebInspector.Timeline.TimelineTypeCookieKey] = this._type;
130     }
131
132     // Private
133
134     _updateTimesIfNeeded(record)
135     {
136         var changed = false;
137
138         if (isNaN(this._startTime) || record.startTime < this._startTime) {
139             this._startTime = record.startTime;
140             changed = true;
141         }
142
143         if (isNaN(this._endTime) || this._endTime < record.endTime) {
144             this._endTime = record.endTime;
145             changed = true;
146         }
147
148         if (changed)
149             this.dispatchEventToListeners(WebInspector.Timeline.Event.TimesUpdated);
150     }
151
152     _recordUpdated(event)
153     {
154         this._updateTimesIfNeeded(event.target);
155     }
156 };
157
158 WebInspector.Timeline.Event = {
159     Reset: "timeline-reset",
160     RecordAdded: "timeline-record-added",
161     TimesUpdated: "timeline-times-updated"
162 };
163
164 WebInspector.Timeline.TimelineTypeCookieKey = "timeline-type";