chrome-devtools-frontend 1.0.1537860 → 1.0.1538310
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.template +3 -2
- package/eslint.config.mjs +151 -149
- package/front_end/core/host/AidaClient.ts +1 -0
- package/front_end/core/host/UserMetrics.ts +3 -1
- package/front_end/core/root/Runtime.ts +8 -0
- package/front_end/models/ai_code_generation/AiCodeGeneration.ts +151 -0
- package/front_end/models/ai_code_generation/ai_code_generation.ts +6 -0
- package/front_end/models/ai_code_generation/debug.ts +30 -0
- package/front_end/panels/application/PreloadingTreeElement.ts +10 -2
- package/front_end/panels/application/components/OriginTrialTreeView.ts +97 -129
- package/front_end/panels/application/components/originTrialTreeView.css +37 -7
- package/front_end/panels/application/preloading/components/PreloadingString.ts +13 -11
- package/front_end/panels/emulation/components/DeviceSizeInputElement.ts +1 -0
- package/front_end/panels/network/NetworkItemView.ts +1 -1
- package/front_end/panels/network/NetworkWaterfallColumn.ts +5 -6
- package/front_end/panels/network/RequestTimingView.ts +404 -348
- package/front_end/panels/network/networkTimingTable.css +22 -2
- package/front_end/panels/timeline/components/NetworkRequestTooltip.ts +42 -3
- package/front_end/panels/timeline/components/networkRequestTooltip.css +19 -0
- package/front_end/ui/components/adorners/Adorner.ts +1 -0
- package/front_end/ui/components/icon_button/IconButton.ts +1 -0
- package/front_end/ui/components/settings/SettingCheckbox.ts +1 -0
- package/front_end/ui/legacy/Treeoutline.ts +15 -0
- package/front_end/ui/legacy/UIUtils.ts +3 -0
- package/front_end/ui/legacy/Widget.ts +6 -4
- package/front_end/ui/legacy/XLink.ts +1 -0
- package/front_end/ui/legacy/components/inline_editor/Swatches.ts +1 -0
- package/front_end/ui/legacy/components/perf_ui/BrickBreaker.ts +1 -0
- package/front_end/ui/legacy/popover.css +12 -11
- package/package.json +1 -1
- package/front_end/panels/application/components/badge.css +0 -33
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import * as Common from '../../core/common/common.js';
|
|
8
8
|
import * as Host from '../../core/host/host.js';
|
|
9
9
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
10
|
+
import * as Platform from '../../core/platform/platform.js';
|
|
10
11
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
11
12
|
import * as Protocol from '../../generated/protocol.js';
|
|
12
13
|
import * as Logs from '../../models/logs/logs.js';
|
|
@@ -14,10 +15,12 @@ import * as NetworkTimeCalculator from '../../models/network_time_calculator/net
|
|
|
14
15
|
import * as uiI18n from '../../ui/i18n/i18n.js';
|
|
15
16
|
import * as ObjectUI from '../../ui/legacy/components/object_ui/object_ui.js';
|
|
16
17
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
18
|
+
import {Directives, html, type LitTemplate, nothing, render} from '../../ui/lit/lit.js';
|
|
17
19
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
18
20
|
|
|
19
21
|
import networkingTimingTableStyles from './networkTimingTable.css.js';
|
|
20
22
|
|
|
23
|
+
const {repeat, classMap, ifDefined} = Directives;
|
|
21
24
|
const UIStrings = {
|
|
22
25
|
/**
|
|
23
26
|
* @description Text used to label the time taken to receive an HTTP/2 Push message.
|
|
@@ -124,7 +127,7 @@ const UIStrings = {
|
|
|
124
127
|
/**
|
|
125
128
|
* @description Text in Request Timing View of the Network panel
|
|
126
129
|
*/
|
|
127
|
-
|
|
130
|
+
requestResponse: 'Request/Response',
|
|
128
131
|
/**
|
|
129
132
|
* @description Text of a DOM element in Request Timing View of the Network panel
|
|
130
133
|
*/
|
|
@@ -212,286 +215,397 @@ const UIStrings = {
|
|
|
212
215
|
* @example {network} PH1
|
|
213
216
|
*/
|
|
214
217
|
routerActualSource: 'Actual source: {PH1}',
|
|
218
|
+
/**
|
|
219
|
+
* @description Cell title in Network Data Grid Node of the Network panel
|
|
220
|
+
* @example {Fast 4G} PH1
|
|
221
|
+
*/
|
|
222
|
+
wasThrottled: 'Request was throttled ({PH1})',
|
|
215
223
|
} as const;
|
|
216
224
|
const str_ = i18n.i18n.registerUIStrings('panels/network/RequestTimingView.ts', UIStrings);
|
|
217
225
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
226
|
+
|
|
227
|
+
function timeRangeTitle(name: NetworkTimeCalculator.RequestTimeRangeNames): string {
|
|
228
|
+
switch (name) {
|
|
229
|
+
case NetworkTimeCalculator.RequestTimeRangeNames.PUSH:
|
|
230
|
+
return i18nString(UIStrings.receivingPush);
|
|
231
|
+
case NetworkTimeCalculator.RequestTimeRangeNames.QUEUEING:
|
|
232
|
+
return i18nString(UIStrings.queueing);
|
|
233
|
+
case NetworkTimeCalculator.RequestTimeRangeNames.BLOCKING:
|
|
234
|
+
return i18nString(UIStrings.stalled);
|
|
235
|
+
case NetworkTimeCalculator.RequestTimeRangeNames.CONNECTING:
|
|
236
|
+
return i18nString(UIStrings.initialConnection);
|
|
237
|
+
case NetworkTimeCalculator.RequestTimeRangeNames.DNS:
|
|
238
|
+
return i18nString(UIStrings.dnsLookup);
|
|
239
|
+
case NetworkTimeCalculator.RequestTimeRangeNames.PROXY:
|
|
240
|
+
return i18nString(UIStrings.proxyNegotiation);
|
|
241
|
+
case NetworkTimeCalculator.RequestTimeRangeNames.RECEIVING_PUSH:
|
|
242
|
+
return i18nString(UIStrings.readingPush);
|
|
243
|
+
case NetworkTimeCalculator.RequestTimeRangeNames.RECEIVING:
|
|
244
|
+
return i18nString(UIStrings.contentDownload);
|
|
245
|
+
case NetworkTimeCalculator.RequestTimeRangeNames.SENDING:
|
|
246
|
+
return i18nString(UIStrings.requestSent);
|
|
247
|
+
case NetworkTimeCalculator.RequestTimeRangeNames.SERVICE_WORKER:
|
|
248
|
+
return i18nString(UIStrings.requestToServiceworker);
|
|
249
|
+
case NetworkTimeCalculator.RequestTimeRangeNames.SERVICE_WORKER_PREPARATION:
|
|
250
|
+
return i18nString(UIStrings.startup);
|
|
251
|
+
case NetworkTimeCalculator.RequestTimeRangeNames.SERVICE_WORKER_ROUTER_EVALUATION:
|
|
252
|
+
return i18nString(UIStrings.routerEvaluation);
|
|
253
|
+
case NetworkTimeCalculator.RequestTimeRangeNames.SERVICE_WORKER_CACHE_LOOKUP:
|
|
254
|
+
return i18nString(UIStrings.routerCacheLookup);
|
|
255
|
+
case NetworkTimeCalculator.RequestTimeRangeNames.SERVICE_WORKER_RESPOND_WITH:
|
|
256
|
+
return i18nString(UIStrings.respondwith);
|
|
257
|
+
case NetworkTimeCalculator.RequestTimeRangeNames.SSL:
|
|
258
|
+
return i18nString(UIStrings.ssl);
|
|
259
|
+
case NetworkTimeCalculator.RequestTimeRangeNames.TOTAL:
|
|
260
|
+
return i18nString(UIStrings.total);
|
|
261
|
+
case NetworkTimeCalculator.RequestTimeRangeNames.WAITING:
|
|
262
|
+
return i18nString(UIStrings.waitingTtfb);
|
|
263
|
+
default:
|
|
264
|
+
return name;
|
|
231
265
|
}
|
|
266
|
+
}
|
|
232
267
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
return i18nString(UIStrings.receivingPush);
|
|
237
|
-
case NetworkTimeCalculator.RequestTimeRangeNames.QUEUEING:
|
|
238
|
-
return i18nString(UIStrings.queueing);
|
|
239
|
-
case NetworkTimeCalculator.RequestTimeRangeNames.BLOCKING:
|
|
240
|
-
return i18nString(UIStrings.stalled);
|
|
241
|
-
case NetworkTimeCalculator.RequestTimeRangeNames.CONNECTING:
|
|
242
|
-
return i18nString(UIStrings.initialConnection);
|
|
243
|
-
case NetworkTimeCalculator.RequestTimeRangeNames.DNS:
|
|
244
|
-
return i18nString(UIStrings.dnsLookup);
|
|
245
|
-
case NetworkTimeCalculator.RequestTimeRangeNames.PROXY:
|
|
246
|
-
return i18nString(UIStrings.proxyNegotiation);
|
|
247
|
-
case NetworkTimeCalculator.RequestTimeRangeNames.RECEIVING_PUSH:
|
|
248
|
-
return i18nString(UIStrings.readingPush);
|
|
249
|
-
case NetworkTimeCalculator.RequestTimeRangeNames.RECEIVING:
|
|
250
|
-
return i18nString(UIStrings.contentDownload);
|
|
251
|
-
case NetworkTimeCalculator.RequestTimeRangeNames.SENDING:
|
|
252
|
-
return i18nString(UIStrings.requestSent);
|
|
253
|
-
case NetworkTimeCalculator.RequestTimeRangeNames.SERVICE_WORKER:
|
|
254
|
-
return i18nString(UIStrings.requestToServiceworker);
|
|
255
|
-
case NetworkTimeCalculator.RequestTimeRangeNames.SERVICE_WORKER_PREPARATION:
|
|
256
|
-
return i18nString(UIStrings.startup);
|
|
257
|
-
case NetworkTimeCalculator.RequestTimeRangeNames.SERVICE_WORKER_ROUTER_EVALUATION:
|
|
258
|
-
return i18nString(UIStrings.routerEvaluation);
|
|
259
|
-
case NetworkTimeCalculator.RequestTimeRangeNames.SERVICE_WORKER_CACHE_LOOKUP:
|
|
260
|
-
return i18nString(UIStrings.routerCacheLookup);
|
|
261
|
-
case NetworkTimeCalculator.RequestTimeRangeNames.SERVICE_WORKER_RESPOND_WITH:
|
|
262
|
-
return i18nString(UIStrings.respondwith);
|
|
263
|
-
case NetworkTimeCalculator.RequestTimeRangeNames.SSL:
|
|
264
|
-
return i18nString(UIStrings.ssl);
|
|
265
|
-
case NetworkTimeCalculator.RequestTimeRangeNames.TOTAL:
|
|
266
|
-
return i18nString(UIStrings.total);
|
|
267
|
-
case NetworkTimeCalculator.RequestTimeRangeNames.WAITING:
|
|
268
|
-
return i18nString(UIStrings.waitingTtfb);
|
|
269
|
-
default:
|
|
270
|
-
return name;
|
|
271
|
-
}
|
|
268
|
+
function groupHeader(name: NetworkTimeCalculator.RequestTimeRangeNames): string {
|
|
269
|
+
if (name === NetworkTimeCalculator.RequestTimeRangeNames.PUSH) {
|
|
270
|
+
return i18nString(UIStrings.serverPush);
|
|
272
271
|
}
|
|
272
|
+
if (name === NetworkTimeCalculator.RequestTimeRangeNames.QUEUEING) {
|
|
273
|
+
return i18nString(UIStrings.resourceScheduling);
|
|
274
|
+
}
|
|
275
|
+
if (NetworkTimeCalculator.ConnectionSetupRangeNames.has(name)) {
|
|
276
|
+
return i18nString(UIStrings.connectionStart);
|
|
277
|
+
}
|
|
278
|
+
if (NetworkTimeCalculator.ServiceWorkerRangeNames.has(name)) {
|
|
279
|
+
return 'Service Worker';
|
|
280
|
+
}
|
|
281
|
+
return i18nString(UIStrings.requestResponse);
|
|
282
|
+
}
|
|
273
283
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
const scale = 100 / (endTime - startTime);
|
|
288
|
-
|
|
289
|
-
let connectionHeader;
|
|
290
|
-
let serviceworkerHeader;
|
|
291
|
-
let dataHeader;
|
|
292
|
-
let queueingHeader;
|
|
293
|
-
let totalDuration = 0;
|
|
294
|
-
|
|
295
|
-
const startTimeHeader = tableElement.createChild('thead', 'network-timing-start');
|
|
296
|
-
const tableHeaderRow = startTimeHeader.createChild('tr');
|
|
297
|
-
const activityHeaderCell = tableHeaderRow.createChild('th');
|
|
298
|
-
activityHeaderCell.createChild('span', 'network-timing-hidden-header').textContent = i18nString(UIStrings.label);
|
|
299
|
-
activityHeaderCell.scope = 'col';
|
|
300
|
-
const waterfallHeaderCell = tableHeaderRow.createChild('th');
|
|
301
|
-
waterfallHeaderCell.createChild('span', 'network-timing-hidden-header').textContent =
|
|
302
|
-
i18nString(UIStrings.waterfall);
|
|
303
|
-
waterfallHeaderCell.scope = 'col';
|
|
304
|
-
const durationHeaderCell = tableHeaderRow.createChild('th');
|
|
305
|
-
durationHeaderCell.createChild('span', 'network-timing-hidden-header').textContent = i18nString(UIStrings.duration);
|
|
306
|
-
durationHeaderCell.scope = 'col';
|
|
307
|
-
|
|
308
|
-
const queuedCell = startTimeHeader.createChild('tr').createChild('td');
|
|
309
|
-
const startedCell = startTimeHeader.createChild('tr').createChild('td');
|
|
310
|
-
queuedCell.colSpan = startedCell.colSpan = 3;
|
|
311
|
-
UI.UIUtils.createTextChild(
|
|
312
|
-
queuedCell, i18nString(UIStrings.queuedAtS, {PH1: calculator.formatValue(request.issueTime(), 2)}));
|
|
313
|
-
UI.UIUtils.createTextChild(
|
|
314
|
-
startedCell, i18nString(UIStrings.startedAtS, {PH1: calculator.formatValue(request.startTime, 2)}));
|
|
315
|
-
|
|
316
|
-
let right;
|
|
317
|
-
for (let i = 0; i < timeRanges.length; ++i) {
|
|
318
|
-
const range = timeRanges[i];
|
|
319
|
-
const rangeName = range.name;
|
|
320
|
-
if (rangeName === NetworkTimeCalculator.RequestTimeRangeNames.TOTAL) {
|
|
321
|
-
totalDuration = range.end - range.start;
|
|
322
|
-
continue;
|
|
323
|
-
}
|
|
324
|
-
if (rangeName === NetworkTimeCalculator.RequestTimeRangeNames.PUSH) {
|
|
325
|
-
createHeader(i18nString(UIStrings.serverPush));
|
|
326
|
-
} else if (rangeName === NetworkTimeCalculator.RequestTimeRangeNames.QUEUEING) {
|
|
327
|
-
if (!queueingHeader) {
|
|
328
|
-
queueingHeader = createHeader(i18nString(UIStrings.resourceScheduling));
|
|
329
|
-
}
|
|
330
|
-
} else if (NetworkTimeCalculator.ConnectionSetupRangeNames.has(rangeName)) {
|
|
331
|
-
if (!connectionHeader) {
|
|
332
|
-
connectionHeader = createHeader(i18nString(UIStrings.connectionStart));
|
|
333
|
-
}
|
|
334
|
-
} else if (NetworkTimeCalculator.ServiceWorkerRangeNames.has(rangeName)) {
|
|
335
|
-
if (!serviceworkerHeader) {
|
|
336
|
-
serviceworkerHeader = createHeader('Service Worker');
|
|
337
|
-
}
|
|
338
|
-
} else if (!dataHeader) {
|
|
339
|
-
dataHeader = createHeader(i18nString(UIStrings.requestresponse));
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
const left = (scale * (range.start - startTime));
|
|
343
|
-
right = (scale * (endTime - range.end));
|
|
344
|
-
const duration = range.end - range.start;
|
|
345
|
-
|
|
346
|
-
const tr = tableElement.createChild('tr');
|
|
347
|
-
const timingBarTitleElement = tr.createChild('td');
|
|
348
|
-
UI.UIUtils.createTextChild(timingBarTitleElement, RequestTimingView.timeRangeTitle(rangeName));
|
|
349
|
-
|
|
350
|
-
const row = tr.createChild('td').createChild('div', 'network-timing-row');
|
|
351
|
-
const bar = row.createChild('span', 'network-timing-bar ' + rangeName);
|
|
352
|
-
bar.style.left = left + '%';
|
|
353
|
-
bar.style.right = right + '%';
|
|
354
|
-
bar.textContent = '\u200B'; // Important for 0-time items to have 0 width.
|
|
355
|
-
UI.ARIAUtils.setLabel(row, i18nString(UIStrings.startedAtS, {PH1: calculator.formatValue(range.start, 2)}));
|
|
356
|
-
const label = tr.createChild('td').createChild('div', 'network-timing-bar-title');
|
|
357
|
-
label.textContent = i18n.TimeUtilities.secondsToString(duration, true);
|
|
358
|
-
|
|
359
|
-
if (range.name === 'serviceworker-respondwith') {
|
|
360
|
-
timingBarTitleElement.classList.add('network-fetch-timing-bar-clickable');
|
|
361
|
-
tableElement.createChild('tr', 'network-fetch-timing-bar-details');
|
|
362
|
-
|
|
363
|
-
timingBarTitleElement.setAttribute('tabindex', '0');
|
|
364
|
-
timingBarTitleElement.setAttribute('role', 'switch');
|
|
365
|
-
UI.ARIAUtils.setChecked(timingBarTitleElement, false);
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
if (range.name === 'serviceworker-routerevaluation') {
|
|
369
|
-
timingBarTitleElement.classList.add('network-fetch-timing-bar-clickable');
|
|
370
|
-
tableElement.createChild('tr', 'router-evaluation-timing-bar-details');
|
|
371
|
-
|
|
372
|
-
timingBarTitleElement.setAttribute('tabindex', '0');
|
|
373
|
-
timingBarTitleElement.setAttribute('role', 'switch');
|
|
374
|
-
UI.ARIAUtils.setChecked(timingBarTitleElement, false);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
284
|
+
function getLocalizedResponseSourceForCode(swResponseSource: Protocol.Network.ServiceWorkerResponseSource):
|
|
285
|
+
Common.UIString.LocalizedString {
|
|
286
|
+
switch (swResponseSource) {
|
|
287
|
+
case Protocol.Network.ServiceWorkerResponseSource.CacheStorage:
|
|
288
|
+
return i18nString(UIStrings.serviceworkerCacheStorage);
|
|
289
|
+
case Protocol.Network.ServiceWorkerResponseSource.HttpCache:
|
|
290
|
+
return i18nString(UIStrings.fromHttpCache);
|
|
291
|
+
case Protocol.Network.ServiceWorkerResponseSource.Network:
|
|
292
|
+
return i18nString(UIStrings.networkFetch);
|
|
293
|
+
default:
|
|
294
|
+
return i18nString(UIStrings.fallbackCode);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
377
297
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
298
|
+
interface ViewInput {
|
|
299
|
+
requestUnfinished: boolean;
|
|
300
|
+
requestStartTime: number;
|
|
301
|
+
requestIssueTime: number;
|
|
302
|
+
totalDuration: number;
|
|
303
|
+
startTime: number;
|
|
304
|
+
endTime: number;
|
|
305
|
+
timeRanges: NetworkTimeCalculator.RequestTimeRange[];
|
|
306
|
+
calculator: NetworkTimeCalculator.NetworkTimeCalculator;
|
|
307
|
+
serverTimings: SDK.ServerTiming.ServerTiming[];
|
|
308
|
+
fetchDetails?: UI.TreeOutline.TreeOutlineInShadow;
|
|
309
|
+
routerDetails?: UI.TreeOutline.TreeOutlineInShadow;
|
|
310
|
+
wasThrottled?: SDK.NetworkManager.Conditions;
|
|
311
|
+
}
|
|
383
312
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
const
|
|
395
|
-
|
|
396
|
-
const
|
|
397
|
-
|
|
398
|
-
const
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
313
|
+
type View = (input: ViewInput, output: object, target: HTMLElement) => void;
|
|
314
|
+
export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
315
|
+
const scale = 100 / (input.endTime - input.startTime);
|
|
316
|
+
const isClickable = (range: NetworkTimeCalculator.RequestTimeRange): boolean =>
|
|
317
|
+
range.name === 'serviceworker-respondwith' || range.name === 'serviceworker-routerevaluation';
|
|
318
|
+
const addServerTiming = (serverTiming: SDK.ServerTiming.ServerTiming): LitTemplate => {
|
|
319
|
+
const colorGenerator =
|
|
320
|
+
new Common.Color.Generator({min: 0, max: 360, count: 36}, {min: 50, max: 80, count: undefined}, 80);
|
|
321
|
+
const isTotal = serverTiming.metric.toLowerCase() === 'total';
|
|
322
|
+
const metricDesc = [serverTiming.metric, serverTiming.description].filter(Boolean).join(' — ');
|
|
323
|
+
const left =
|
|
324
|
+
serverTiming.value === null ? -1 : scale * (input.endTime - input.startTime - (serverTiming.value / 1000));
|
|
325
|
+
const lastRange =
|
|
326
|
+
input.timeRanges.findLast(range => range.name !== NetworkTimeCalculator.RequestTimeRangeNames.TOTAL);
|
|
327
|
+
const lastTimingRightEdge = lastRange ? (scale * (input.endTime - lastRange.end)) : 100;
|
|
328
|
+
|
|
329
|
+
const classes = classMap({
|
|
330
|
+
['network-timing-footer']: isTotal,
|
|
331
|
+
['server-timing-row']: !isTotal,
|
|
332
|
+
// Mark entries from a bespoke format
|
|
333
|
+
['synthetic']: serverTiming.metric.startsWith('(c'),
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
// clang-format off
|
|
337
|
+
return html`
|
|
338
|
+
<tr class=${classes}>
|
|
339
|
+
<td title=${metricDesc} class=network-timing-metric>
|
|
340
|
+
${metricDesc}
|
|
341
|
+
</td>
|
|
342
|
+
${serverTiming.value === null ? nothing : html`
|
|
343
|
+
<td class=server-timing-cell--value-bar>
|
|
344
|
+
<div class=network-timing-row>
|
|
345
|
+
${left < 0 // don't chart values too big or too small
|
|
346
|
+
? nothing
|
|
347
|
+
: html`<span
|
|
348
|
+
class="network-timing-bar server-timing"
|
|
349
|
+
data-background=${ifDefined(isTotal ? undefined : colorGenerator.colorForID(serverTiming.metric))}
|
|
350
|
+
data-left=${left}
|
|
351
|
+
data-right=${lastTimingRightEdge}>${'\u200B'}</span>`}
|
|
352
|
+
</div>
|
|
353
|
+
</td>
|
|
354
|
+
<td class=server-timing-cell--value-text>
|
|
355
|
+
<div class=network-timing-bar-title>
|
|
356
|
+
${i18n.TimeUtilities.millisToString(serverTiming.value, true)}
|
|
357
|
+
</div>
|
|
358
|
+
</td>
|
|
359
|
+
`}
|
|
360
|
+
</tr>`;
|
|
361
|
+
// clang-format on
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
const onActivate = (e: KeyboardEvent|MouseEvent): void => {
|
|
365
|
+
if ('key' in e && !Platform.KeyboardUtilities.isEnterOrSpaceKey(e)) {
|
|
366
|
+
return;
|
|
419
367
|
}
|
|
368
|
+
const target = e.target as Element | null;
|
|
369
|
+
if (!target?.classList.contains('network-fetch-timing-bar-clickable')) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const isChecked = target.ariaChecked === 'false';
|
|
373
|
+
target.ariaChecked = isChecked ? 'true' : 'false';
|
|
374
|
+
if (!isChecked) {
|
|
375
|
+
Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelServiceWorkerRespondWith);
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
const throttledRequestTitle = input.wasThrottled ?
|
|
380
|
+
i18nString(
|
|
381
|
+
UIStrings.wasThrottled,
|
|
382
|
+
{PH1: typeof input.wasThrottled.title === 'string' ? input.wasThrottled.title : input.wasThrottled.title()}) :
|
|
383
|
+
undefined;
|
|
384
|
+
|
|
385
|
+
const classes = classMap({
|
|
386
|
+
['network-timing-table']: true,
|
|
387
|
+
['resource-timing-table']: true,
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
const timeRangeGroups: Array<{name: string, ranges: NetworkTimeCalculator.RequestTimeRange[]}> = [];
|
|
391
|
+
for (const range of input.timeRanges) {
|
|
392
|
+
if (range.name === NetworkTimeCalculator.RequestTimeRangeNames.TOTAL) {
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
const groupName = groupHeader(range.name);
|
|
396
|
+
const tail = timeRangeGroups.at(-1);
|
|
397
|
+
if (tail?.name !== groupName) {
|
|
398
|
+
timeRangeGroups.push({name: groupName, ranges: [range]});
|
|
399
|
+
} else {
|
|
400
|
+
tail.ranges.push(range);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
420
403
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
404
|
+
render(
|
|
405
|
+
// clang-format off
|
|
406
|
+
html`<style>${networkingTimingTableStyles}</style>
|
|
407
|
+
<table
|
|
408
|
+
class=${classes}
|
|
409
|
+
jslog=${VisualLogging.pane('timing').track({
|
|
410
|
+
resize: true
|
|
411
|
+
})}>
|
|
412
|
+
<colgroup>
|
|
413
|
+
<col class=labels></col>
|
|
414
|
+
<col class=bars> </col>
|
|
415
|
+
<col class=duration></col>
|
|
416
|
+
</colgroup>
|
|
417
|
+
<thead class=network-timing-start>
|
|
418
|
+
<tr>
|
|
419
|
+
<th scope=col>
|
|
420
|
+
<span class=network-timing-hidden-header>${i18nString(UIStrings.label)}</span>
|
|
421
|
+
</th>
|
|
422
|
+
<th scope=col>
|
|
423
|
+
<span class=network-timing-hidden-header>${i18nString(UIStrings.waterfall)}</span>
|
|
424
|
+
</th>
|
|
425
|
+
<th scope=col>
|
|
426
|
+
<span class=network-timing-hidden-header>${i18nString(UIStrings.duration)}</span>
|
|
427
|
+
</th>
|
|
428
|
+
</tr>
|
|
429
|
+
<tr>
|
|
430
|
+
<td colspan = 3>
|
|
431
|
+
${i18nString(UIStrings.queuedAtS, {PH1: input.calculator.formatValue(input.requestIssueTime, 2)})}
|
|
432
|
+
</td>
|
|
433
|
+
</tr>
|
|
434
|
+
<tr>
|
|
435
|
+
<td colspan=3>
|
|
436
|
+
${i18nString(UIStrings.startedAtS, {PH1: input.calculator.formatValue(input.requestStartTime, 2)})}
|
|
437
|
+
</td>
|
|
438
|
+
</tr>
|
|
439
|
+
</thead>
|
|
440
|
+
${timeRangeGroups.map(group => html`
|
|
441
|
+
<tr class=network-timing-table-header>
|
|
442
|
+
<td role=heading aria-level=2>
|
|
443
|
+
${group.name}
|
|
444
|
+
</td>
|
|
445
|
+
<td></td>
|
|
446
|
+
<td>${i18nString(UIStrings.durationC)}</td>
|
|
447
|
+
</tr>
|
|
448
|
+
${repeat(group.ranges, range => html`
|
|
449
|
+
<tr>
|
|
450
|
+
${isClickable(range) ? html`<td
|
|
451
|
+
tabindex=0
|
|
452
|
+
role=switch
|
|
453
|
+
aria-checked=false
|
|
454
|
+
@click=${onActivate}
|
|
455
|
+
@keydown=${onActivate}
|
|
456
|
+
class=network-fetch-timing-bar-clickable>
|
|
457
|
+
${timeRangeTitle(range.name)}
|
|
458
|
+
</td>`
|
|
459
|
+
: html`<td>
|
|
460
|
+
${timeRangeTitle(range.name)}
|
|
461
|
+
</td>`}
|
|
462
|
+
<td>
|
|
463
|
+
<div
|
|
464
|
+
class=network-timing-row
|
|
465
|
+
aria-label=${i18nString(UIStrings.startedAtS, {PH1: input.calculator.formatValue(range.start, 2)})}>
|
|
466
|
+
<span
|
|
467
|
+
class="network-timing-bar ${range.name}"
|
|
468
|
+
data-left=${scale * (range.start - input.startTime)}
|
|
469
|
+
data-right=${scale * (input.endTime - range.end)}>${'\u200B'}</span>
|
|
470
|
+
</div>
|
|
471
|
+
</td>
|
|
472
|
+
<td>
|
|
473
|
+
<div class=network-timing-bar-title>
|
|
474
|
+
${i18n.TimeUtilities.secondsToString(range.end - range.start, true)}
|
|
475
|
+
</div>
|
|
476
|
+
</td>
|
|
477
|
+
</tr>
|
|
478
|
+
${range.name === 'serviceworker-respondwith' && input.fetchDetails ? html`
|
|
479
|
+
<tr class="network-fetch-timing-bar-details network-fetch-timing-bar-details-collapsed">
|
|
480
|
+
${input.fetchDetails.element}
|
|
481
|
+
</tr>`
|
|
482
|
+
: nothing}
|
|
483
|
+
${range.name === 'serviceworker-routerevaluation' && input.routerDetails ? html`
|
|
484
|
+
<tr class="router-evaluation-timing-bar-details network-fetch-timing-bar-details-collapsed">
|
|
485
|
+
${input.routerDetails.element}
|
|
486
|
+
</tr>`
|
|
487
|
+
: nothing}
|
|
488
|
+
`)}
|
|
489
|
+
`)}
|
|
490
|
+
${input.requestUnfinished ? html`
|
|
491
|
+
<tr>
|
|
492
|
+
<td class=caution colspan=3>
|
|
493
|
+
${i18nString(UIStrings.cautionRequestIsNotFinishedYet)}
|
|
494
|
+
</td>
|
|
495
|
+
</tr>` : nothing}
|
|
496
|
+
<tr class=network-timing-footer>
|
|
497
|
+
<td colspan=1>
|
|
498
|
+
<x-link
|
|
499
|
+
href="https://developer.chrome.com/docs/devtools/network/reference/#timing-explanation"
|
|
500
|
+
class=devtools-link
|
|
501
|
+
jslog=${VisualLogging.link().track({click: true, keydown:'Enter|Space'}).context('explanation')}>
|
|
502
|
+
${i18nString(UIStrings.explanation)}
|
|
503
|
+
</x-link>
|
|
504
|
+
<td></td>
|
|
505
|
+
<td class=${input.wasThrottled ? 'throttled' : ''} title=${ifDefined(throttledRequestTitle)}>
|
|
506
|
+
${input.wasThrottled ? html` <devtools-icon name=watch ></devtools-icon>` : nothing}
|
|
507
|
+
${i18n.TimeUtilities.secondsToString(input.totalDuration, true)}
|
|
508
|
+
</td>
|
|
509
|
+
</tr>
|
|
510
|
+
<tr class=network-timing-table-header>
|
|
511
|
+
<td colspan=3>
|
|
512
|
+
<hr class=break />
|
|
513
|
+
</td>
|
|
514
|
+
</tr>
|
|
515
|
+
<tr class=network-timing-table-header>
|
|
516
|
+
<td>${i18nString(UIStrings.serverTiming)}</td>
|
|
517
|
+
<td></td>
|
|
518
|
+
<td>${i18nString(UIStrings.time)}</td>
|
|
519
|
+
</tr>
|
|
520
|
+
${repeat(input.serverTimings.filter(item => item.metric.toLowerCase() !== 'total'), addServerTiming)}
|
|
521
|
+
${repeat(input.serverTimings.filter(item => item.metric.toLowerCase() === 'total'), addServerTiming)}
|
|
522
|
+
${input.serverTimings.length === 0 ? html`
|
|
523
|
+
<tr>
|
|
524
|
+
<td colspan=3>
|
|
525
|
+
${uiI18n.getFormatLocalizedString(str_, UIStrings.duringDevelopmentYouCanUseSToAdd, {PH1:
|
|
526
|
+
UI.XLink.XLink.create(
|
|
527
|
+
'https://web.dev/custom-metrics/#server-timing-api',
|
|
528
|
+
i18nString(UIStrings.theServerTimingApi),
|
|
529
|
+
undefined,
|
|
530
|
+
undefined,
|
|
531
|
+
'server-timing-api')})}
|
|
532
|
+
</td>
|
|
533
|
+
</tr>` : nothing}
|
|
534
|
+
</table>`,
|
|
535
|
+
// clang-format on
|
|
536
|
+
target);
|
|
537
|
+
};
|
|
435
538
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
if (serverTiming.value === null) {
|
|
447
|
-
return;
|
|
448
|
-
}
|
|
449
|
-
const left = scale * (endTime - startTime - (serverTiming.value / 1000));
|
|
450
|
-
if (left >= 0) { // don't chart values too big or too small
|
|
451
|
-
const bar = row.createChild('span', 'network-timing-bar server-timing');
|
|
452
|
-
bar.style.left = left + '%';
|
|
453
|
-
bar.style.right = right + '%';
|
|
454
|
-
bar.textContent = '\u200B'; // Important for 0-time items to have 0 width.
|
|
455
|
-
if (!isTotal) {
|
|
456
|
-
bar.style.backgroundColor = colorGenerator.colorForID(serverTiming.metric);
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
const label =
|
|
460
|
-
tr.createChild('td', 'server-timing-cell--value-text').createChild('div', 'network-timing-bar-title');
|
|
461
|
-
label.textContent = i18n.TimeUtilities.millisToString(serverTiming.value, true);
|
|
462
|
-
}
|
|
539
|
+
export class RequestTimingView extends UI.Widget.VBox {
|
|
540
|
+
#request?: SDK.NetworkRequest.NetworkRequest;
|
|
541
|
+
#calculator?: NetworkTimeCalculator.NetworkTimeCalculator;
|
|
542
|
+
#lastMinimumBoundary = -1;
|
|
543
|
+
readonly #view: View;
|
|
544
|
+
constructor(target?: HTMLElement, view = DEFAULT_VIEW) {
|
|
545
|
+
super(target, {classes: ['resource-timing-view']});
|
|
546
|
+
this.#view = view;
|
|
547
|
+
}
|
|
463
548
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
return dataHeader;
|
|
472
|
-
}
|
|
549
|
+
static create(request: SDK.NetworkRequest.NetworkRequest, calculator: NetworkTimeCalculator.NetworkTimeCalculator):
|
|
550
|
+
RequestTimingView {
|
|
551
|
+
const view = new RequestTimingView();
|
|
552
|
+
view.request = request;
|
|
553
|
+
view.calculator = calculator;
|
|
554
|
+
view.requestUpdate();
|
|
555
|
+
return view;
|
|
473
556
|
}
|
|
474
557
|
|
|
475
|
-
|
|
476
|
-
if (!this
|
|
558
|
+
override performUpdate(): void {
|
|
559
|
+
if (!this.#request || !this.#calculator) {
|
|
477
560
|
return;
|
|
478
561
|
}
|
|
562
|
+
const timeRanges =
|
|
563
|
+
NetworkTimeCalculator.calculateRequestTimeRanges(this.#request, this.#calculator.minimumBoundary());
|
|
564
|
+
const startTime = timeRanges.map(r => r.start).reduce((a, b) => Math.min(a, b));
|
|
565
|
+
const endTime = timeRanges.map(r => r.end).reduce((a, b) => Math.max(a, b));
|
|
566
|
+
const total = timeRanges.findLast(range => range.name === NetworkTimeCalculator.RequestTimeRangeNames.TOTAL);
|
|
567
|
+
const totalDuration = total ? total?.end - total?.start : 0;
|
|
568
|
+
const conditions = SDK.NetworkManager.MultitargetNetworkManager.instance().appliedRequestConditions(this.#request);
|
|
569
|
+
|
|
570
|
+
const input: ViewInput = {
|
|
571
|
+
startTime,
|
|
572
|
+
endTime,
|
|
573
|
+
totalDuration,
|
|
574
|
+
serverTimings: this.#request.serverTimings ?? [],
|
|
575
|
+
calculator: this.#calculator,
|
|
576
|
+
requestStartTime: this.#request.startTime,
|
|
577
|
+
requestIssueTime: this.#request.issueTime(),
|
|
578
|
+
requestUnfinished: false,
|
|
579
|
+
fetchDetails: this.#fetchDetailsTree(),
|
|
580
|
+
routerDetails: this.#routerDetailsTree(),
|
|
581
|
+
wasThrottled: conditions?.urlPattern ? conditions.conditions : undefined,
|
|
582
|
+
timeRanges,
|
|
583
|
+
};
|
|
584
|
+
this.#view(input, {}, this.contentElement);
|
|
585
|
+
}
|
|
479
586
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
if (!fetchDetailsElement) {
|
|
587
|
+
private onToggleFetchDetails(fetchDetailsElement: Element, event: Event): void {
|
|
588
|
+
if (!event.target) {
|
|
484
589
|
return;
|
|
485
590
|
}
|
|
486
591
|
|
|
487
|
-
|
|
592
|
+
const target = (event.target as Element);
|
|
593
|
+
if (target.classList.contains('network-fetch-timing-bar-clickable')) {
|
|
594
|
+
const expanded = target.getAttribute('aria-checked') === 'true';
|
|
595
|
+
target.setAttribute('aria-checked', String(!expanded));
|
|
488
596
|
|
|
489
|
-
|
|
597
|
+
fetchDetailsElement.classList.toggle('network-fetch-timing-bar-details-collapsed');
|
|
598
|
+
fetchDetailsElement.classList.toggle('network-fetch-timing-bar-details-expanded');
|
|
599
|
+
}
|
|
600
|
+
}
|
|
490
601
|
|
|
602
|
+
#fetchDetailsTree(): UI.TreeOutline.TreeOutlineInShadow|undefined {
|
|
603
|
+
if (!this.#request?.fetchedViaServiceWorker) {
|
|
604
|
+
return undefined;
|
|
605
|
+
}
|
|
491
606
|
const detailsView = new UI.TreeOutline.TreeOutlineInShadow();
|
|
492
|
-
fetchDetailsElement.appendChild(detailsView.element);
|
|
493
607
|
|
|
494
|
-
const origRequest = Logs.NetworkLog.NetworkLog.instance().originalRequestForURL(this
|
|
608
|
+
const origRequest = Logs.NetworkLog.NetworkLog.instance().originalRequestForURL(this.#request.url());
|
|
495
609
|
if (origRequest) {
|
|
496
610
|
const requestObject = SDK.RemoteObject.RemoteObject.fromLocalObject(origRequest);
|
|
497
611
|
const requestTreeElement = new ObjectUI.ObjectPropertiesSection.RootElement(requestObject);
|
|
@@ -499,7 +613,7 @@ export class RequestTimingView extends UI.Widget.VBox {
|
|
|
499
613
|
detailsView.appendChild(requestTreeElement);
|
|
500
614
|
}
|
|
501
615
|
|
|
502
|
-
const response = Logs.NetworkLog.NetworkLog.instance().originalResponseForURL(this
|
|
616
|
+
const response = Logs.NetworkLog.NetworkLog.instance().originalResponseForURL(this.#request.url());
|
|
503
617
|
if (response) {
|
|
504
618
|
const responseObject = SDK.RemoteObject.RemoteObject.fromLocalObject(response);
|
|
505
619
|
const responseTreeElement = new ObjectUI.ObjectPropertiesSection.RootElement(responseObject);
|
|
@@ -510,9 +624,9 @@ export class RequestTimingView extends UI.Widget.VBox {
|
|
|
510
624
|
const serviceWorkerResponseSource = document.createElement('div');
|
|
511
625
|
serviceWorkerResponseSource.classList.add('network-fetch-details-treeitem');
|
|
512
626
|
let swResponseSourceString = i18nString(UIStrings.unknown);
|
|
513
|
-
const swResponseSource = this
|
|
627
|
+
const swResponseSource = this.#request.serviceWorkerResponseSource();
|
|
514
628
|
if (swResponseSource) {
|
|
515
|
-
swResponseSourceString =
|
|
629
|
+
swResponseSourceString = getLocalizedResponseSourceForCode(swResponseSource);
|
|
516
630
|
}
|
|
517
631
|
serviceWorkerResponseSource.textContent = i18nString(UIStrings.sourceOfResponseS, {PH1: swResponseSourceString});
|
|
518
632
|
|
|
@@ -521,7 +635,7 @@ export class RequestTimingView extends UI.Widget.VBox {
|
|
|
521
635
|
|
|
522
636
|
const cacheNameElement = document.createElement('div');
|
|
523
637
|
cacheNameElement.classList.add('network-fetch-details-treeitem');
|
|
524
|
-
const responseCacheStorageName = this
|
|
638
|
+
const responseCacheStorageName = this.#request.getResponseCacheStorageCacheName();
|
|
525
639
|
if (responseCacheStorageName) {
|
|
526
640
|
cacheNameElement.textContent = i18nString(UIStrings.cacheStorageCacheNameS, {PH1: responseCacheStorageName});
|
|
527
641
|
} else {
|
|
@@ -531,7 +645,7 @@ export class RequestTimingView extends UI.Widget.VBox {
|
|
|
531
645
|
const cacheNameTreeElement = new UI.TreeOutline.TreeElement(cacheNameElement);
|
|
532
646
|
detailsView.appendChild(cacheNameTreeElement);
|
|
533
647
|
|
|
534
|
-
const retrievalTime = this
|
|
648
|
+
const retrievalTime = this.#request.getResponseRetrievalTime();
|
|
535
649
|
if (retrievalTime) {
|
|
536
650
|
const responseTimeElement = document.createElement('div');
|
|
537
651
|
responseTimeElement.classList.add('network-fetch-details-treeitem');
|
|
@@ -539,65 +653,21 @@ export class RequestTimingView extends UI.Widget.VBox {
|
|
|
539
653
|
const responseTimeTreeElement = new UI.TreeOutline.TreeElement(responseTimeElement);
|
|
540
654
|
detailsView.appendChild(responseTimeTreeElement);
|
|
541
655
|
}
|
|
656
|
+
return detailsView;
|
|
542
657
|
}
|
|
543
658
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
case Protocol.Network.ServiceWorkerResponseSource.CacheStorage:
|
|
548
|
-
return i18nString(UIStrings.serviceworkerCacheStorage);
|
|
549
|
-
case Protocol.Network.ServiceWorkerResponseSource.HttpCache:
|
|
550
|
-
return i18nString(UIStrings.fromHttpCache);
|
|
551
|
-
case Protocol.Network.ServiceWorkerResponseSource.Network:
|
|
552
|
-
return i18nString(UIStrings.networkFetch);
|
|
553
|
-
default:
|
|
554
|
-
return i18nString(UIStrings.fallbackCode);
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
private onToggleFetchDetails(fetchDetailsElement: Element, event: Event): void {
|
|
559
|
-
if (!event.target) {
|
|
560
|
-
return;
|
|
659
|
+
#routerDetailsTree(): UI.TreeOutline.TreeOutlineInShadow|undefined {
|
|
660
|
+
if (!this.#request?.serviceWorkerRouterInfo) {
|
|
661
|
+
return undefined;
|
|
561
662
|
}
|
|
562
663
|
|
|
563
|
-
const target = (event.target as Element);
|
|
564
|
-
if (target.classList.contains('network-fetch-timing-bar-clickable')) {
|
|
565
|
-
if (fetchDetailsElement.classList.contains('network-fetch-timing-bar-details-collapsed')) {
|
|
566
|
-
Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelServiceWorkerRespondWith);
|
|
567
|
-
}
|
|
568
|
-
const expanded = target.getAttribute('aria-checked') === 'true';
|
|
569
|
-
target.setAttribute('aria-checked', String(!expanded));
|
|
570
|
-
|
|
571
|
-
fetchDetailsElement.classList.toggle('network-fetch-timing-bar-details-collapsed');
|
|
572
|
-
fetchDetailsElement.classList.toggle('network-fetch-timing-bar-details-expanded');
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
private constructRouterEvaluationView(): void {
|
|
577
|
-
if (!this.tableElement) {
|
|
578
|
-
return;
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
const routerEvaluationDetailsElement = this.tableElement.querySelector('.router-evaluation-timing-bar-details');
|
|
582
|
-
if (!routerEvaluationDetailsElement) {
|
|
583
|
-
return;
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
routerEvaluationDetailsElement.classList.add('network-fetch-timing-bar-details-collapsed');
|
|
587
|
-
|
|
588
|
-
self.onInvokeElement(
|
|
589
|
-
this.tableElement, this.onToggleRouterEvaluationDetails.bind(this, routerEvaluationDetailsElement));
|
|
590
|
-
|
|
591
664
|
const detailsView = new UI.TreeOutline.TreeOutlineInShadow();
|
|
592
|
-
routerEvaluationDetailsElement.appendChild(detailsView.element);
|
|
593
665
|
|
|
594
|
-
const {serviceWorkerRouterInfo} = this
|
|
666
|
+
const {serviceWorkerRouterInfo} = this.#request;
|
|
595
667
|
if (!serviceWorkerRouterInfo) {
|
|
596
668
|
return;
|
|
597
669
|
}
|
|
598
670
|
|
|
599
|
-
const document = this.tableElement.ownerDocument;
|
|
600
|
-
|
|
601
671
|
// Add matched source type element
|
|
602
672
|
const matchedSourceTypeElement = document.createElement('div');
|
|
603
673
|
matchedSourceTypeElement.classList.add('network-fetch-details-treeitem');
|
|
@@ -617,61 +687,47 @@ export class RequestTimingView extends UI.Widget.VBox {
|
|
|
617
687
|
|
|
618
688
|
const actualSourceTypeTreeElement = new UI.TreeOutline.TreeElement(actualSourceTypeElement);
|
|
619
689
|
detailsView.appendChild(actualSourceTypeTreeElement);
|
|
690
|
+
|
|
691
|
+
return detailsView;
|
|
620
692
|
}
|
|
621
693
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
694
|
+
set request(request: SDK.NetworkRequest.NetworkRequest) {
|
|
695
|
+
this.#request = request;
|
|
696
|
+
if (this.isShowing()) {
|
|
697
|
+
this.#request.addEventListener(SDK.NetworkRequest.Events.TIMING_CHANGED, this.requestUpdate, this);
|
|
698
|
+
this.#request.addEventListener(SDK.NetworkRequest.Events.FINISHED_LOADING, this.requestUpdate, this);
|
|
699
|
+
this.requestUpdate();
|
|
625
700
|
}
|
|
701
|
+
}
|
|
626
702
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
routerEvaluationDetailsElement.classList.toggle('network-fetch-timing-bar-details-collapsed');
|
|
633
|
-
routerEvaluationDetailsElement.classList.toggle('network-fetch-timing-bar-details-expanded');
|
|
703
|
+
set calculator(calculator: NetworkTimeCalculator.NetworkTimeCalculator) {
|
|
704
|
+
this.#calculator = calculator;
|
|
705
|
+
if (this.isShowing()) {
|
|
706
|
+
this.#calculator.addEventListener(NetworkTimeCalculator.Events.BOUNDARIES_CHANGED, this.boundaryChanged, this);
|
|
707
|
+
this.requestUpdate();
|
|
634
708
|
}
|
|
635
709
|
}
|
|
636
710
|
|
|
637
711
|
override wasShown(): void {
|
|
638
712
|
super.wasShown();
|
|
639
|
-
this
|
|
640
|
-
this
|
|
641
|
-
this
|
|
642
|
-
this.
|
|
713
|
+
this.#request?.addEventListener(SDK.NetworkRequest.Events.TIMING_CHANGED, this.requestUpdate, this);
|
|
714
|
+
this.#request?.addEventListener(SDK.NetworkRequest.Events.FINISHED_LOADING, this.requestUpdate, this);
|
|
715
|
+
this.#calculator?.addEventListener(NetworkTimeCalculator.Events.BOUNDARIES_CHANGED, this.boundaryChanged, this);
|
|
716
|
+
this.requestUpdate();
|
|
643
717
|
}
|
|
644
718
|
|
|
645
719
|
override willHide(): void {
|
|
646
720
|
super.willHide();
|
|
647
|
-
this
|
|
648
|
-
this
|
|
649
|
-
this
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
private refresh(): void {
|
|
653
|
-
if (this.tableElement) {
|
|
654
|
-
this.tableElement.remove();
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
this.tableElement = RequestTimingView.createTimingTable(this.request, this.calculator);
|
|
658
|
-
this.tableElement.classList.add('resource-timing-table');
|
|
659
|
-
this.element.appendChild(this.tableElement);
|
|
660
|
-
|
|
661
|
-
if (this.request.fetchedViaServiceWorker) {
|
|
662
|
-
this.constructFetchDetailsView();
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
if (this.request.serviceWorkerRouterInfo) {
|
|
666
|
-
this.constructRouterEvaluationView();
|
|
667
|
-
}
|
|
721
|
+
this.#request?.removeEventListener(SDK.NetworkRequest.Events.TIMING_CHANGED, this.requestUpdate, this);
|
|
722
|
+
this.#request?.removeEventListener(SDK.NetworkRequest.Events.FINISHED_LOADING, this.requestUpdate, this);
|
|
723
|
+
this.#calculator?.removeEventListener(NetworkTimeCalculator.Events.BOUNDARIES_CHANGED, this.boundaryChanged, this);
|
|
668
724
|
}
|
|
669
725
|
|
|
670
726
|
private boundaryChanged(): void {
|
|
671
727
|
const minimumBoundary = this.calculator.minimumBoundary();
|
|
672
|
-
if (minimumBoundary !== this
|
|
673
|
-
this
|
|
674
|
-
this.
|
|
728
|
+
if (minimumBoundary !== this.#lastMinimumBoundary) {
|
|
729
|
+
this.#lastMinimumBoundary = minimumBoundary;
|
|
730
|
+
this.requestUpdate();
|
|
675
731
|
}
|
|
676
732
|
}
|
|
677
733
|
}
|