OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | |
5 /** | 4 /** |
6 * @constructor | 5 * @unrestricted |
7 * @extends {WebInspector.TimelineOverviewBase} | |
8 */ | 6 */ |
9 WebInspector.NetworkOverview = function() | 7 WebInspector.NetworkOverview = class extends WebInspector.TimelineOverviewBase { |
10 { | 8 constructor() { |
11 WebInspector.TimelineOverviewBase.call(this); | 9 super(); |
12 this.element.classList.add("network-overview"); | 10 this.element.classList.add('network-overview'); |
13 | 11 |
14 /** @type {number} */ | 12 /** @type {number} */ |
15 this._numBands = 1; | 13 this._numBands = 1; |
16 /** @type {number} */ | 14 /** @type {number} */ |
17 this._windowStart = 0; | 15 this._windowStart = 0; |
18 /** @type {number} */ | 16 /** @type {number} */ |
19 this._windowEnd = 0; | 17 this._windowEnd = 0; |
20 /** @type {boolean} */ | 18 /** @type {boolean} */ |
21 this._restoringWindow = false; | 19 this._restoringWindow = false; |
22 /** @type {boolean} */ | 20 /** @type {boolean} */ |
23 this._updateScheduled = false; | 21 this._updateScheduled = false; |
24 /** @type {number} */ | 22 /** @type {number} */ |
25 this._canvasWidth = 0; | 23 this._canvasWidth = 0; |
26 /** @type {number} */ | 24 /** @type {number} */ |
27 this._canvasHeight = 0; | 25 this._canvasHeight = 0; |
28 | 26 |
29 WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel,
WebInspector.ResourceTreeModel.Events.Load, this._loadEventFired, this); | 27 WebInspector.targetManager.addModelListener( |
30 WebInspector.targetManager.addModelListener(WebInspector.ResourceTreeModel,
WebInspector.ResourceTreeModel.Events.DOMContentLoaded, this._domContentLoadedEv
entFired, this); | 28 WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.Events.Lo
ad, this._loadEventFired, this); |
| 29 WebInspector.targetManager.addModelListener( |
| 30 WebInspector.ResourceTreeModel, WebInspector.ResourceTreeModel.Events.DO
MContentLoaded, |
| 31 this._domContentLoadedEventFired, this); |
31 | 32 |
32 this.reset(); | 33 this.reset(); |
| 34 } |
| 35 |
| 36 /** |
| 37 * @param {?WebInspector.FilmStripModel} filmStripModel |
| 38 */ |
| 39 setFilmStripModel(filmStripModel) { |
| 40 this._filmStripModel = filmStripModel; |
| 41 this.scheduleUpdate(); |
| 42 } |
| 43 |
| 44 /** |
| 45 * @param {number} time |
| 46 */ |
| 47 selectFilmStripFrame(time) { |
| 48 this._selectedFilmStripTime = time; |
| 49 this.scheduleUpdate(); |
| 50 } |
| 51 |
| 52 clearFilmStripFrame() { |
| 53 this._selectedFilmStripTime = -1; |
| 54 this.scheduleUpdate(); |
| 55 } |
| 56 |
| 57 /** |
| 58 * @param {!WebInspector.Event} event |
| 59 */ |
| 60 _loadEventFired(event) { |
| 61 var data = /** @type {number} */ (event.data); |
| 62 if (data) |
| 63 this._loadEvents.push(data * 1000); |
| 64 this.scheduleUpdate(); |
| 65 } |
| 66 |
| 67 /** |
| 68 * @param {!WebInspector.Event} event |
| 69 */ |
| 70 _domContentLoadedEventFired(event) { |
| 71 var data = /** @type {number} */ (event.data); |
| 72 if (data) |
| 73 this._domContentLoadedEvents.push(data * 1000); |
| 74 this.scheduleUpdate(); |
| 75 } |
| 76 |
| 77 /** |
| 78 * @param {string} connectionId |
| 79 * @return {number} |
| 80 */ |
| 81 _bandId(connectionId) { |
| 82 if (!connectionId || connectionId === '0') |
| 83 return -1; |
| 84 if (this._bandMap.has(connectionId)) |
| 85 return /** @type {number} */ (this._bandMap.get(connectionId)); |
| 86 var result = this._nextBand++; |
| 87 this._bandMap.set(connectionId, result); |
| 88 return result; |
| 89 } |
| 90 |
| 91 /** |
| 92 * @param {!WebInspector.NetworkRequest} request |
| 93 */ |
| 94 updateRequest(request) { |
| 95 if (!this._requestsSet.has(request)) { |
| 96 this._requestsSet.add(request); |
| 97 this._requestsList.push(request); |
| 98 } |
| 99 this.scheduleUpdate(); |
| 100 } |
| 101 |
| 102 /** |
| 103 * @override |
| 104 */ |
| 105 wasShown() { |
| 106 this.onResize(); |
| 107 } |
| 108 |
| 109 /** |
| 110 * @override |
| 111 */ |
| 112 onResize() { |
| 113 var width = this.element.offsetWidth; |
| 114 var height = this.element.offsetHeight; |
| 115 this._calculator.setDisplayWindow(width); |
| 116 this.resetCanvas(); |
| 117 var numBands = (((height - 1) / WebInspector.NetworkOverview._bandHeight) -
1) | 0; |
| 118 this._numBands = (numBands > 0) ? numBands : 1; |
| 119 this.scheduleUpdate(); |
| 120 } |
| 121 |
| 122 /** |
| 123 * @override |
| 124 */ |
| 125 reset() { |
| 126 this._windowStart = 0; |
| 127 this._windowEnd = 0; |
| 128 /** @type {?WebInspector.FilmStripModel} */ |
| 129 this._filmStripModel = null; |
| 130 |
| 131 /** @type {number} */ |
| 132 this._span = 1; |
| 133 /** @type {?WebInspector.NetworkTimeBoundary} */ |
| 134 this._lastBoundary = null; |
| 135 /** @type {number} */ |
| 136 this._nextBand = 0; |
| 137 /** @type {!Map.<string, number>} */ |
| 138 this._bandMap = new Map(); |
| 139 /** @type {!Array.<!WebInspector.NetworkRequest>} */ |
| 140 this._requestsList = []; |
| 141 /** @type {!Set.<!WebInspector.NetworkRequest>} */ |
| 142 this._requestsSet = new Set(); |
| 143 /** @type {!Array.<number>} */ |
| 144 this._loadEvents = []; |
| 145 /** @type {!Array.<number>} */ |
| 146 this._domContentLoadedEvents = []; |
| 147 |
| 148 // Clear screen. |
| 149 this.resetCanvas(); |
| 150 } |
| 151 |
| 152 /** |
| 153 * @protected |
| 154 */ |
| 155 scheduleUpdate() { |
| 156 if (this._updateScheduled || !this.isShowing()) |
| 157 return; |
| 158 this._updateScheduled = true; |
| 159 this.element.window().requestAnimationFrame(this.update.bind(this)); |
| 160 } |
| 161 |
| 162 /** |
| 163 * @override |
| 164 */ |
| 165 update() { |
| 166 this._updateScheduled = false; |
| 167 |
| 168 var newBoundary = |
| 169 new WebInspector.NetworkTimeBoundary(this._calculator.minimumBoundary(),
this._calculator.maximumBoundary()); |
| 170 if (!this._lastBoundary || !newBoundary.equals(this._lastBoundary)) { |
| 171 var span = this._calculator.boundarySpan(); |
| 172 while (this._span < span) |
| 173 this._span *= 1.25; |
| 174 this._calculator.setBounds(this._calculator.minimumBoundary(), this._calcu
lator.minimumBoundary() + this._span); |
| 175 this._lastBoundary = |
| 176 new WebInspector.NetworkTimeBoundary(this._calculator.minimumBoundary(
), this._calculator.maximumBoundary()); |
| 177 if (this._windowStart || this._windowEnd) { |
| 178 this._restoringWindow = true; |
| 179 var startTime = this._calculator.minimumBoundary(); |
| 180 var totalTime = this._calculator.boundarySpan(); |
| 181 var left = (this._windowStart - startTime) / totalTime; |
| 182 var right = (this._windowEnd - startTime) / totalTime; |
| 183 this._restoringWindow = false; |
| 184 } |
| 185 } |
| 186 |
| 187 var context = this._canvas.getContext('2d'); |
| 188 var calculator = this._calculator; |
| 189 var linesByType = {}; |
| 190 var paddingTop = 2; |
| 191 |
| 192 /** |
| 193 * @param {string} type |
| 194 * @param {string} strokeStyle |
| 195 */ |
| 196 function drawLines(type, strokeStyle) { |
| 197 var lines = linesByType[type]; |
| 198 if (!lines) |
| 199 return; |
| 200 var n = lines.length; |
| 201 context.beginPath(); |
| 202 context.strokeStyle = strokeStyle; |
| 203 for (var i = 0; i < n;) { |
| 204 var y = lines[i++] * WebInspector.NetworkOverview._bandHeight + paddingT
op; |
| 205 var startTime = lines[i++]; |
| 206 var endTime = lines[i++]; |
| 207 if (endTime === Number.MAX_VALUE) |
| 208 endTime = calculator.maximumBoundary(); |
| 209 context.moveTo(calculator.computePosition(startTime), y); |
| 210 context.lineTo(calculator.computePosition(endTime) + 1, y); |
| 211 } |
| 212 context.stroke(); |
| 213 } |
| 214 |
| 215 /** |
| 216 * @param {string} type |
| 217 * @param {number} y |
| 218 * @param {number} start |
| 219 * @param {number} end |
| 220 */ |
| 221 function addLine(type, y, start, end) { |
| 222 var lines = linesByType[type]; |
| 223 if (!lines) { |
| 224 lines = []; |
| 225 linesByType[type] = lines; |
| 226 } |
| 227 lines.push(y, start, end); |
| 228 } |
| 229 |
| 230 var requests = this._requestsList; |
| 231 var n = requests.length; |
| 232 for (var i = 0; i < n; ++i) { |
| 233 var request = requests[i]; |
| 234 var band = this._bandId(request.connectionId); |
| 235 var y = (band === -1) ? 0 : (band % this._numBands + 1); |
| 236 var timeRanges = |
| 237 WebInspector.RequestTimingView.calculateRequestTimeRanges(request, thi
s._calculator.minimumBoundary()); |
| 238 for (var j = 0; j < timeRanges.length; ++j) { |
| 239 var type = timeRanges[j].name; |
| 240 if (band !== -1 || type === WebInspector.RequestTimeRangeNames.Total) |
| 241 addLine(type, y, timeRanges[j].start * 1000, timeRanges[j].end * 1000)
; |
| 242 } |
| 243 } |
| 244 |
| 245 context.clearRect(0, 0, this._canvas.width, this._canvas.height); |
| 246 context.save(); |
| 247 context.scale(window.devicePixelRatio, window.devicePixelRatio); |
| 248 context.lineWidth = 2; |
| 249 drawLines(WebInspector.RequestTimeRangeNames.Total, '#CCCCCC'); |
| 250 drawLines(WebInspector.RequestTimeRangeNames.Blocking, '#AAAAAA'); |
| 251 drawLines(WebInspector.RequestTimeRangeNames.Connecting, '#FF9800'); |
| 252 drawLines(WebInspector.RequestTimeRangeNames.ServiceWorker, '#FF9800'); |
| 253 drawLines(WebInspector.RequestTimeRangeNames.ServiceWorkerPreparation, '#FF9
800'); |
| 254 drawLines(WebInspector.RequestTimeRangeNames.Push, '#8CDBff'); |
| 255 drawLines(WebInspector.RequestTimeRangeNames.Proxy, '#A1887F'); |
| 256 drawLines(WebInspector.RequestTimeRangeNames.DNS, '#009688'); |
| 257 drawLines(WebInspector.RequestTimeRangeNames.SSL, '#9C27B0'); |
| 258 drawLines(WebInspector.RequestTimeRangeNames.Sending, '#B0BEC5'); |
| 259 drawLines(WebInspector.RequestTimeRangeNames.Waiting, '#00C853'); |
| 260 drawLines(WebInspector.RequestTimeRangeNames.Receiving, '#03A9F4'); |
| 261 |
| 262 var height = this.element.offsetHeight; |
| 263 context.lineWidth = 1; |
| 264 context.beginPath(); |
| 265 context.strokeStyle = '#8080FF'; // Keep in sync with .network-blue-divider
CSS rule. |
| 266 for (var i = this._domContentLoadedEvents.length - 1; i >= 0; --i) { |
| 267 var x = Math.round(calculator.computePosition(this._domContentLoadedEvents
[i])) + 0.5; |
| 268 context.moveTo(x, 0); |
| 269 context.lineTo(x, height); |
| 270 } |
| 271 context.stroke(); |
| 272 |
| 273 context.beginPath(); |
| 274 context.strokeStyle = '#FF8080'; // Keep in sync with .network-red-divider
CSS rule. |
| 275 for (var i = this._loadEvents.length - 1; i >= 0; --i) { |
| 276 var x = Math.round(calculator.computePosition(this._loadEvents[i])) + 0.5; |
| 277 context.moveTo(x, 0); |
| 278 context.lineTo(x, height); |
| 279 } |
| 280 context.stroke(); |
| 281 |
| 282 if (this._selectedFilmStripTime !== -1) { |
| 283 context.lineWidth = 2; |
| 284 context.beginPath(); |
| 285 context.strokeStyle = '#FCCC49'; // Keep in sync with .network-frame-divi
der CSS rule. |
| 286 var x = Math.round(calculator.computePosition(this._selectedFilmStripTime)
); |
| 287 context.moveTo(x, 0); |
| 288 context.lineTo(x, height); |
| 289 context.stroke(); |
| 290 } |
| 291 context.restore(); |
| 292 } |
33 }; | 293 }; |
34 | 294 |
35 /** @type {number} */ | 295 /** @type {number} */ |
36 WebInspector.NetworkOverview._bandHeight = 3; | 296 WebInspector.NetworkOverview._bandHeight = 3; |
37 | 297 |
38 /** @typedef {{start: number, end: number}} */ | 298 /** @typedef {{start: number, end: number}} */ |
39 WebInspector.NetworkOverview.Window; | 299 WebInspector.NetworkOverview.Window; |
40 | |
41 WebInspector.NetworkOverview.prototype = { | |
42 /** | |
43 * @param {?WebInspector.FilmStripModel} filmStripModel | |
44 */ | |
45 setFilmStripModel: function(filmStripModel) | |
46 { | |
47 this._filmStripModel = filmStripModel; | |
48 this.scheduleUpdate(); | |
49 }, | |
50 | |
51 /** | |
52 * @param {number} time | |
53 */ | |
54 selectFilmStripFrame: function(time) | |
55 { | |
56 this._selectedFilmStripTime = time; | |
57 this.scheduleUpdate(); | |
58 }, | |
59 | |
60 clearFilmStripFrame: function() | |
61 { | |
62 this._selectedFilmStripTime = -1; | |
63 this.scheduleUpdate(); | |
64 }, | |
65 | |
66 /** | |
67 * @param {!WebInspector.Event} event | |
68 */ | |
69 _loadEventFired: function(event) | |
70 { | |
71 var data = /** @type {number} */ (event.data); | |
72 if (data) | |
73 this._loadEvents.push(data * 1000); | |
74 this.scheduleUpdate(); | |
75 }, | |
76 | |
77 /** | |
78 * @param {!WebInspector.Event} event | |
79 */ | |
80 _domContentLoadedEventFired: function(event) | |
81 { | |
82 var data = /** @type {number} */ (event.data); | |
83 if (data) | |
84 this._domContentLoadedEvents.push(data * 1000); | |
85 this.scheduleUpdate(); | |
86 }, | |
87 | |
88 /** | |
89 * @param {string} connectionId | |
90 * @return {number} | |
91 */ | |
92 _bandId: function(connectionId) | |
93 { | |
94 if (!connectionId || connectionId === "0") | |
95 return -1; | |
96 if (this._bandMap.has(connectionId)) | |
97 return /** @type {number} */ (this._bandMap.get(connectionId)); | |
98 var result = this._nextBand++; | |
99 this._bandMap.set(connectionId, result); | |
100 return result; | |
101 }, | |
102 | |
103 /** | |
104 * @param {!WebInspector.NetworkRequest} request | |
105 */ | |
106 updateRequest: function(request) | |
107 { | |
108 if (!this._requestsSet.has(request)) { | |
109 this._requestsSet.add(request); | |
110 this._requestsList.push(request); | |
111 } | |
112 this.scheduleUpdate(); | |
113 }, | |
114 | |
115 /** | |
116 * @override | |
117 */ | |
118 wasShown: function() | |
119 { | |
120 this.onResize(); | |
121 }, | |
122 | |
123 /** | |
124 * @override | |
125 */ | |
126 onResize: function() | |
127 { | |
128 var width = this.element.offsetWidth; | |
129 var height = this.element.offsetHeight; | |
130 this._calculator.setDisplayWindow(width); | |
131 this.resetCanvas(); | |
132 var numBands = (((height - 1) / WebInspector.NetworkOverview._bandHeight
) - 1) | 0; | |
133 this._numBands = (numBands > 0) ? numBands : 1; | |
134 this.scheduleUpdate(); | |
135 }, | |
136 | |
137 /** | |
138 * @override | |
139 */ | |
140 reset: function() | |
141 { | |
142 this._windowStart = 0; | |
143 this._windowEnd = 0; | |
144 /** @type {?WebInspector.FilmStripModel} */ | |
145 this._filmStripModel = null; | |
146 | |
147 /** @type {number} */ | |
148 this._span = 1; | |
149 /** @type {?WebInspector.NetworkTimeBoundary} */ | |
150 this._lastBoundary = null; | |
151 /** @type {number} */ | |
152 this._nextBand = 0; | |
153 /** @type {!Map.<string, number>} */ | |
154 this._bandMap = new Map(); | |
155 /** @type {!Array.<!WebInspector.NetworkRequest>} */ | |
156 this._requestsList = []; | |
157 /** @type {!Set.<!WebInspector.NetworkRequest>} */ | |
158 this._requestsSet = new Set(); | |
159 /** @type {!Array.<number>} */ | |
160 this._loadEvents = []; | |
161 /** @type {!Array.<number>} */ | |
162 this._domContentLoadedEvents = []; | |
163 | |
164 // Clear screen. | |
165 this.resetCanvas(); | |
166 }, | |
167 | |
168 /** | |
169 * @protected | |
170 */ | |
171 scheduleUpdate: function() | |
172 { | |
173 if (this._updateScheduled || !this.isShowing()) | |
174 return; | |
175 this._updateScheduled = true; | |
176 this.element.window().requestAnimationFrame(this.update.bind(this)); | |
177 }, | |
178 | |
179 /** | |
180 * @override | |
181 */ | |
182 update: function() | |
183 { | |
184 this._updateScheduled = false; | |
185 | |
186 var newBoundary = new WebInspector.NetworkTimeBoundary(this._calculator.
minimumBoundary(), this._calculator.maximumBoundary()); | |
187 if (!this._lastBoundary || !newBoundary.equals(this._lastBoundary)) { | |
188 var span = this._calculator.boundarySpan(); | |
189 while (this._span < span) | |
190 this._span *= 1.25; | |
191 this._calculator.setBounds(this._calculator.minimumBoundary(), this.
_calculator.minimumBoundary() + this._span); | |
192 this._lastBoundary = new WebInspector.NetworkTimeBoundary(this._calc
ulator.minimumBoundary(), this._calculator.maximumBoundary()); | |
193 if (this._windowStart || this._windowEnd) { | |
194 this._restoringWindow = true; | |
195 var startTime = this._calculator.minimumBoundary(); | |
196 var totalTime = this._calculator.boundarySpan(); | |
197 var left = (this._windowStart - startTime) / totalTime; | |
198 var right = (this._windowEnd - startTime) / totalTime; | |
199 this._restoringWindow = false; | |
200 } | |
201 } | |
202 | |
203 var context = this._canvas.getContext("2d"); | |
204 var calculator = this._calculator; | |
205 var linesByType = {}; | |
206 var paddingTop = 2; | |
207 | |
208 /** | |
209 * @param {string} type | |
210 * @param {string} strokeStyle | |
211 */ | |
212 function drawLines(type, strokeStyle) | |
213 { | |
214 var lines = linesByType[type]; | |
215 if (!lines) | |
216 return; | |
217 var n = lines.length; | |
218 context.beginPath(); | |
219 context.strokeStyle = strokeStyle; | |
220 for (var i = 0; i < n;) { | |
221 var y = lines[i++] * WebInspector.NetworkOverview._bandHeight +
paddingTop; | |
222 var startTime = lines[i++]; | |
223 var endTime = lines[i++]; | |
224 if (endTime === Number.MAX_VALUE) | |
225 endTime = calculator.maximumBoundary(); | |
226 context.moveTo(calculator.computePosition(startTime), y); | |
227 context.lineTo(calculator.computePosition(endTime) + 1, y); | |
228 } | |
229 context.stroke(); | |
230 } | |
231 | |
232 /** | |
233 * @param {string} type | |
234 * @param {number} y | |
235 * @param {number} start | |
236 * @param {number} end | |
237 */ | |
238 function addLine(type, y, start, end) | |
239 { | |
240 var lines = linesByType[type]; | |
241 if (!lines) { | |
242 lines = []; | |
243 linesByType[type] = lines; | |
244 } | |
245 lines.push(y, start, end); | |
246 } | |
247 | |
248 var requests = this._requestsList; | |
249 var n = requests.length; | |
250 for (var i = 0; i < n; ++i) { | |
251 var request = requests[i]; | |
252 var band = this._bandId(request.connectionId); | |
253 var y = (band === -1) ? 0 : (band % this._numBands + 1); | |
254 var timeRanges = WebInspector.RequestTimingView.calculateRequestTime
Ranges(request, this._calculator.minimumBoundary()); | |
255 for (var j = 0; j < timeRanges.length; ++j) { | |
256 var type = timeRanges[j].name; | |
257 if (band !== -1 || type === WebInspector.RequestTimeRangeNames.T
otal) | |
258 addLine(type, y, timeRanges[j].start * 1000, timeRanges[j].e
nd * 1000); | |
259 } | |
260 } | |
261 | |
262 context.clearRect(0, 0, this._canvas.width, this._canvas.height); | |
263 context.save(); | |
264 context.scale(window.devicePixelRatio, window.devicePixelRatio); | |
265 context.lineWidth = 2; | |
266 drawLines(WebInspector.RequestTimeRangeNames.Total, "#CCCCCC"); | |
267 drawLines(WebInspector.RequestTimeRangeNames.Blocking, "#AAAAAA"); | |
268 drawLines(WebInspector.RequestTimeRangeNames.Connecting, "#FF9800"); | |
269 drawLines(WebInspector.RequestTimeRangeNames.ServiceWorker, "#FF9800"); | |
270 drawLines(WebInspector.RequestTimeRangeNames.ServiceWorkerPreparation, "
#FF9800"); | |
271 drawLines(WebInspector.RequestTimeRangeNames.Push, "#8CDBff"); | |
272 drawLines(WebInspector.RequestTimeRangeNames.Proxy, "#A1887F"); | |
273 drawLines(WebInspector.RequestTimeRangeNames.DNS, "#009688"); | |
274 drawLines(WebInspector.RequestTimeRangeNames.SSL, "#9C27B0"); | |
275 drawLines(WebInspector.RequestTimeRangeNames.Sending, "#B0BEC5"); | |
276 drawLines(WebInspector.RequestTimeRangeNames.Waiting, "#00C853"); | |
277 drawLines(WebInspector.RequestTimeRangeNames.Receiving, "#03A9F4"); | |
278 | |
279 var height = this.element.offsetHeight; | |
280 context.lineWidth = 1; | |
281 context.beginPath(); | |
282 context.strokeStyle = "#8080FF"; // Keep in sync with .network-blue-divi
der CSS rule. | |
283 for (var i = this._domContentLoadedEvents.length - 1; i >= 0; --i) { | |
284 var x = Math.round(calculator.computePosition(this._domContentLoaded
Events[i])) + 0.5; | |
285 context.moveTo(x, 0); | |
286 context.lineTo(x, height); | |
287 } | |
288 context.stroke(); | |
289 | |
290 context.beginPath(); | |
291 context.strokeStyle = "#FF8080"; // Keep in sync with .network-red-divid
er CSS rule. | |
292 for (var i = this._loadEvents.length - 1; i >= 0; --i) { | |
293 var x = Math.round(calculator.computePosition(this._loadEvents[i]))
+ 0.5; | |
294 context.moveTo(x, 0); | |
295 context.lineTo(x, height); | |
296 } | |
297 context.stroke(); | |
298 | |
299 if (this._selectedFilmStripTime !== -1) { | |
300 context.lineWidth = 2; | |
301 context.beginPath(); | |
302 context.strokeStyle = "#FCCC49"; // Keep in sync with .network-frame
-divider CSS rule. | |
303 var x = Math.round(calculator.computePosition(this._selectedFilmStri
pTime)); | |
304 context.moveTo(x, 0); | |
305 context.lineTo(x, height); | |
306 context.stroke(); | |
307 } | |
308 context.restore(); | |
309 }, | |
310 | |
311 __proto__: WebInspector.TimelineOverviewBase.prototype | |
312 }; | |
OLD | NEW |