chrome-devtools-frontend 1.0.1532228 → 1.0.1532884

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.
Files changed (108) hide show
  1. package/AUTHORS +1 -0
  2. package/front_end/core/platform/ArrayUtilities.ts +1 -1
  3. package/front_end/core/protocol_client/ConnectionTransport.ts +26 -0
  4. package/front_end/core/protocol_client/InspectorBackend.ts +9 -36
  5. package/front_end/core/protocol_client/protocol_client.ts +2 -0
  6. package/front_end/core/root/Runtime.ts +0 -2
  7. package/front_end/core/sdk/ChildTargetManager.ts +3 -3
  8. package/front_end/core/sdk/Connections.ts +8 -8
  9. package/front_end/core/sdk/NetworkManager.ts +20 -0
  10. package/front_end/core/sdk/RehydratingConnection.ts +6 -4
  11. package/front_end/core/sdk/Target.ts +2 -1
  12. package/front_end/core/sdk/TargetManager.ts +2 -1
  13. package/front_end/entrypoints/node_app/NodeMain.ts +1 -1
  14. package/front_end/models/trace/extras/TraceTree.ts +13 -3
  15. package/front_end/panels/console/ConsoleInsightTeaser.ts +40 -48
  16. package/front_end/panels/console/consoleInsightTeaser.css +13 -0
  17. package/front_end/panels/lighthouse/LighthousePanel.ts +1 -1
  18. package/front_end/panels/lighthouse/LighthouseProtocolService.ts +1 -1
  19. package/front_end/panels/network/RequestConditionsDrawer.ts +44 -11
  20. package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +18 -6
  21. package/front_end/panels/sources/SourcesPanel.ts +10 -9
  22. package/front_end/panels/timeline/TimelinePanel.ts +1 -2
  23. package/front_end/panels/timeline/TimingsTrackAppender.ts +10 -8
  24. package/front_end/panels/timeline/components/ExportTraceOptions.ts +2 -8
  25. package/front_end/third_party/puppeteer/README.chromium +2 -2
  26. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/HTTPRequest.d.ts +1 -1
  27. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +2 -2
  28. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
  29. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.d.ts.map +1 -1
  30. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.js +20 -14
  31. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.js.map +1 -1
  32. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Connection.d.ts.map +1 -1
  33. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Connection.js +16 -0
  34. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Connection.js.map +1 -1
  35. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
  36. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.js +2 -4
  37. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.js.map +1 -1
  38. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Realm.d.ts +2 -2
  39. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Request.d.ts +1 -0
  40. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Request.d.ts.map +1 -1
  41. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Request.js +30 -4
  42. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Request.js.map +1 -1
  43. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js +18 -0
  44. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js.map +1 -1
  45. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/ExecutionContext.d.ts.map +1 -1
  46. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/ExecutionContext.js.map +1 -1
  47. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPRequest.d.ts.map +1 -1
  48. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPRequest.js +2 -1
  49. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPRequest.js.map +1 -1
  50. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPResponse.js +1 -1
  51. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPResponse.js.map +1 -1
  52. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/JSHandle.js.map +1 -1
  53. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/utils.d.ts +2 -2
  54. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/utils.d.ts.map +1 -1
  55. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  56. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  57. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  58. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  59. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +3 -3
  60. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +22 -3
  61. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/HTTPRequest.d.ts +1 -1
  62. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +2 -2
  63. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
  64. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.d.ts.map +1 -1
  65. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.js +20 -14
  66. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.js.map +1 -1
  67. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Connection.d.ts.map +1 -1
  68. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Connection.js +16 -0
  69. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Connection.js.map +1 -1
  70. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
  71. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.js +2 -4
  72. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.js.map +1 -1
  73. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Request.d.ts +1 -0
  74. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Request.d.ts.map +1 -1
  75. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Request.js +31 -5
  76. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Request.js.map +1 -1
  77. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js +18 -0
  78. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js.map +1 -1
  79. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/ExecutionContext.d.ts.map +1 -1
  80. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/ExecutionContext.js.map +1 -1
  81. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPRequest.d.ts.map +1 -1
  82. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPRequest.js +2 -1
  83. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPRequest.js.map +1 -1
  84. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPResponse.js +1 -1
  85. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPResponse.js.map +1 -1
  86. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/JSHandle.js.map +1 -1
  87. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/utils.d.ts +2 -2
  88. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/utils.d.ts.map +1 -1
  89. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  90. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  91. package/front_end/third_party/puppeteer/package/lib/types.d.ts +3 -3
  92. package/front_end/third_party/puppeteer/package/package.json +5 -4
  93. package/front_end/third_party/puppeteer/package/src/api/HTTPRequest.ts +1 -1
  94. package/front_end/third_party/puppeteer/package/src/api/Page.ts +2 -2
  95. package/front_end/third_party/puppeteer/package/src/bidi/Browser.ts +24 -14
  96. package/front_end/third_party/puppeteer/package/src/bidi/Connection.ts +16 -0
  97. package/front_end/third_party/puppeteer/package/src/bidi/HTTPRequest.ts +2 -4
  98. package/front_end/third_party/puppeteer/package/src/bidi/core/Request.ts +35 -5
  99. package/front_end/third_party/puppeteer/package/src/cdp/Accessibility.ts +20 -0
  100. package/front_end/third_party/puppeteer/package/src/cdp/ExecutionContext.ts +6 -2
  101. package/front_end/third_party/puppeteer/package/src/cdp/HTTPRequest.ts +2 -1
  102. package/front_end/third_party/puppeteer/package/src/cdp/HTTPResponse.ts +1 -1
  103. package/front_end/third_party/puppeteer/package/src/cdp/JSHandle.ts +1 -1
  104. package/front_end/third_party/puppeteer/package/src/cdp/utils.ts +2 -2
  105. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  106. package/front_end/ui/components/tooltips/Tooltip.ts +5 -0
  107. package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
  108. package/package.json +1 -1
package/AUTHORS CHANGED
@@ -81,6 +81,7 @@ Ross Wollman <ross.wollman@gmail.com>
81
81
  Royi Hagigi <rhagigi@gmail.com>
82
82
  Ryan Puhalovich <reanpuhalovich@gmail.com>
83
83
  Ryuhei Shima <shimaryuhei@gmail.com>
84
+ Samuel Maddock <samuelmaddock@electronjs.org>
84
85
  Satvic Dhawan <satvicdhawan14@gmail.com>
85
86
  Sebastian Markbåge <sebastian@calyptus.eu>
86
87
  Serg Kryvonos <sergeikrivonos@gmail.com>
@@ -22,7 +22,7 @@ export const removeElement = <T>(array: T[], element: T, firstOnly?: boolean): b
22
22
 
23
23
  type NumberComparator = (a: number, b: number) => number;
24
24
 
25
- function swap(array: number[], i1: number, i2: number): void {
25
+ export function swap<T>(array: T[], i1: number, i2: number): void {
26
26
  const temp = array[i1];
27
27
  array[i1] = array[i2];
28
28
  array[i2] = temp;
@@ -0,0 +1,26 @@
1
+ // Copyright 2025 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ let connectionFactory: () => ConnectionTransport;
6
+
7
+ export abstract class ConnectionTransport {
8
+ declare onMessage: ((arg0: Object) => void)|null;
9
+
10
+ // on message from browser
11
+ abstract setOnMessage(onMessage: (arg0: Object|string) => void): void;
12
+ abstract setOnDisconnect(onDisconnect: (arg0: string) => void): void;
13
+
14
+ // send raw CDP message to browser
15
+ abstract sendRawMessage(message: string): void;
16
+
17
+ abstract disconnect(): Promise<void>;
18
+
19
+ static setFactory(factory: () => ConnectionTransport): void {
20
+ connectionFactory = factory;
21
+ }
22
+
23
+ static getFactory(): () => ConnectionTransport {
24
+ return connectionFactory;
25
+ }
26
+ }
@@ -7,6 +7,7 @@ import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js';
7
7
  import type * as Protocol from '../../generated/protocol.js';
8
8
  import type * as Platform from '../platform/platform.js';
9
9
 
10
+ import {ConnectionTransport} from './ConnectionTransport.js';
10
11
  import {NodeURL} from './NodeURL.js';
11
12
 
12
13
  export const DevToolsStubErrorCode = -32015;
@@ -160,35 +161,6 @@ export class InspectorBackend {
160
161
  }
161
162
  }
162
163
 
163
- let connectionFactory: () => Connection;
164
-
165
- export class Connection {
166
- declare onMessage: ((arg0: Object) => void)|null;
167
-
168
- // on message from browser
169
- setOnMessage(_onMessage: (arg0: Object|string) => void): void {
170
- }
171
-
172
- setOnDisconnect(_onDisconnect: (arg0: string) => void): void {
173
- }
174
-
175
- // send raw CDP message to browser
176
- sendRawMessage(_message: string): void {
177
- }
178
-
179
- disconnect(): Promise<void> {
180
- throw new Error('not implemented');
181
- }
182
-
183
- static setFactory(factory: () => Connection): void {
184
- connectionFactory = factory;
185
- }
186
-
187
- static getFactory(): () => Connection {
188
- return connectionFactory;
189
- }
190
- }
191
-
192
164
  type SendRawMessageCallback = (...args: unknown[]) => void;
193
165
 
194
166
  export const test = {
@@ -232,18 +204,18 @@ export const test = {
232
204
  const LongPollingMethods = new Set<string>(['CSS.takeComputedStyleUpdates']);
233
205
 
234
206
  export class SessionRouter {
235
- readonly #connection: Connection;
207
+ readonly #connection: ConnectionTransport;
236
208
  #lastMessageId = 1;
237
209
  #pendingResponsesCount = 0;
238
210
  readonly #pendingLongPollingMessageIds = new Set<number>();
239
211
  readonly #sessions = new Map<string, {
240
212
  target: TargetBase,
241
213
  callbacks: Map<number, CallbackWithDebugInfo>,
242
- proxyConnection: Connection|undefined|null,
214
+ proxyConnection: ConnectionTransport|undefined|null,
243
215
  }>();
244
216
  #pendingScripts: Array<() => void> = [];
245
217
 
246
- constructor(connection: Connection) {
218
+ constructor(connection: ConnectionTransport) {
247
219
  this.#connection = connection;
248
220
 
249
221
  test.deprecatedRunAfterPendingDispatches = this.deprecatedRunAfterPendingDispatches.bind(this);
@@ -259,7 +231,7 @@ export class SessionRouter {
259
231
  });
260
232
  }
261
233
 
262
- registerSession(target: TargetBase, sessionId: string, proxyConnection?: Connection|null): void {
234
+ registerSession(target: TargetBase, sessionId: string, proxyConnection?: ConnectionTransport|null): void {
263
235
  // Only the Audits panel uses proxy connections. If it is ever possible to have multiple active at the
264
236
  // same time, it should be tested thoroughly.
265
237
  if (proxyConnection) {
@@ -297,7 +269,7 @@ export class SessionRouter {
297
269
  return this.#lastMessageId++;
298
270
  }
299
271
 
300
- connection(): Connection {
272
+ connection(): ConnectionTransport {
301
273
  return this.#connection;
302
274
  }
303
275
 
@@ -497,7 +469,8 @@ export class TargetBase {
497
469
  #dispatchers: DispatcherMap = new Map();
498
470
 
499
471
  constructor(
500
- needsNodeJSPatching: boolean, parentTarget: TargetBase|null, sessionId: string, connection: Connection|null) {
472
+ needsNodeJSPatching: boolean, parentTarget: TargetBase|null, sessionId: string,
473
+ connection: ConnectionTransport|null) {
501
474
  this.needsNodeJSPatching = needsNodeJSPatching;
502
475
  this.sessionId = sessionId;
503
476
 
@@ -511,7 +484,7 @@ export class TargetBase {
511
484
  } else if (connection) {
512
485
  router = new SessionRouter(connection);
513
486
  } else {
514
- router = new SessionRouter(connectionFactory());
487
+ router = new SessionRouter(ConnectionTransport.getFactory()());
515
488
  }
516
489
 
517
490
  this.#router = router;
@@ -2,10 +2,12 @@
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
 
5
+ import * as ConnectionTransport from './ConnectionTransport.js';
5
6
  import * as InspectorBackend from './InspectorBackend.js';
6
7
  import * as NodeURL from './NodeURL.js';
7
8
 
8
9
  export {
10
+ ConnectionTransport,
9
11
  InspectorBackend,
10
12
  NodeURL,
11
13
  };
@@ -343,8 +343,6 @@ export const enum ExperimentName {
343
343
  USE_SOURCE_MAP_SCOPES = 'use-source-map-scopes',
344
344
  TIMELINE_SHOW_POST_MESSAGE_EVENTS = 'timeline-show-postmessage-events',
345
345
  TIMELINE_DEBUG_MODE = 'timeline-debug-mode',
346
- TIMELINE_ENHANCED_TRACES = 'timeline-enhanced-traces',
347
- TIMELINE_COMPILED_SOURCES = 'timeline-compiled-sources',
348
346
  // Adding or removing an entry from this enum?
349
347
  // You will need to update:
350
348
  // 1. REGISTERED_EXPERIMENTS in EnvironmentHelpers.ts (to create this experiment in the test env)
@@ -36,7 +36,7 @@ export class ChildTargetManager extends SDKModel<EventTypes> implements Protocol
36
36
  readonly #targetInfos = new Map<Protocol.Target.TargetID, Protocol.Target.TargetInfo>();
37
37
  readonly #childTargetsBySessionId = new Map<Protocol.Target.SessionID, Target>();
38
38
  readonly #childTargetsById = new Map<Protocol.Target.TargetID|'main', Target>();
39
- readonly #parallelConnections = new Map<string, ProtocolClient.InspectorBackend.Connection>();
39
+ readonly #parallelConnections = new Map<string, ProtocolClient.ConnectionTransport.ConnectionTransport>();
40
40
  #parentTargetId: Protocol.Target.TargetID|null = null;
41
41
 
42
42
  constructor(parentTarget: Target) {
@@ -261,7 +261,7 @@ export class ChildTargetManager extends SDKModel<EventTypes> implements Protocol
261
261
  }
262
262
 
263
263
  async createParallelConnection(onMessage: (arg0: Object|string) => void):
264
- Promise<{connection: ProtocolClient.InspectorBackend.Connection, sessionId: string}> {
264
+ Promise<{connection: ProtocolClient.ConnectionTransport.ConnectionTransport, sessionId: string}> {
265
265
  // The main Target id is actually just `main`, instead of the real targetId.
266
266
  // Get the real id (requires an async operation) so that it can be used synchronously later.
267
267
  const targetId = await this.getParentTargetId();
@@ -274,7 +274,7 @@ export class ChildTargetManager extends SDKModel<EventTypes> implements Protocol
274
274
 
275
275
  private async createParallelConnectionAndSessionForTarget(target: Target, targetId: Protocol.Target.TargetID):
276
276
  Promise<{
277
- connection: ProtocolClient.InspectorBackend.Connection,
277
+ connection: ProtocolClient.ConnectionTransport.ConnectionTransport,
278
278
  sessionId: string,
279
279
  }> {
280
280
  const targetAgent = target.targetAgent();
@@ -19,7 +19,7 @@ const UIStrings = {
19
19
  } as const;
20
20
  const str_ = i18n.i18n.registerUIStrings('core/sdk/Connections.ts', UIStrings);
21
21
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
22
- export class MainConnection implements ProtocolClient.InspectorBackend.Connection {
22
+ export class MainConnection implements ProtocolClient.ConnectionTransport.ConnectionTransport {
23
23
  onMessage: ((arg0: Object|string) => void)|null = null;
24
24
  #onDisconnect: ((arg0: string) => void)|null = null;
25
25
  #messageBuffer = '';
@@ -81,7 +81,7 @@ export class MainConnection implements ProtocolClient.InspectorBackend.Connectio
81
81
  }
82
82
  }
83
83
 
84
- export class WebSocketConnection implements ProtocolClient.InspectorBackend.Connection {
84
+ export class WebSocketConnection implements ProtocolClient.ConnectionTransport.ConnectionTransport {
85
85
  #socket: WebSocket|null;
86
86
  onMessage: ((arg0: Object|string) => void)|null = null;
87
87
  #onDisconnect: ((arg0: string) => void)|null = null;
@@ -176,7 +176,7 @@ export class WebSocketConnection implements ProtocolClient.InspectorBackend.Conn
176
176
  }
177
177
  }
178
178
 
179
- export class StubConnection implements ProtocolClient.InspectorBackend.Connection {
179
+ export class StubConnection implements ProtocolClient.ConnectionTransport.ConnectionTransport {
180
180
  onMessage: ((arg0: Object|string) => void)|null = null;
181
181
  #onDisconnect: ((arg0: string) => void)|null = null;
182
182
 
@@ -213,17 +213,17 @@ export class StubConnection implements ProtocolClient.InspectorBackend.Connectio
213
213
  }
214
214
  }
215
215
 
216
- export interface ParallelConnectionInterface extends ProtocolClient.InspectorBackend.Connection {
216
+ export interface ParallelConnectionInterface extends ProtocolClient.ConnectionTransport.ConnectionTransport {
217
217
  getSessionId: () => string;
218
218
  getOnDisconnect: () => ((arg0: string) => void) | null;
219
219
  }
220
220
 
221
221
  export class ParallelConnection implements ParallelConnectionInterface {
222
- readonly #connection: ProtocolClient.InspectorBackend.Connection;
222
+ readonly #connection: ProtocolClient.ConnectionTransport.ConnectionTransport;
223
223
  #sessionId: string;
224
224
  onMessage: ((arg0: Object) => void)|null = null;
225
225
  #onDisconnect: ((arg0: string) => void)|null = null;
226
- constructor(connection: ProtocolClient.InspectorBackend.Connection, sessionId: string) {
226
+ constructor(connection: ProtocolClient.ConnectionTransport.ConnectionTransport, sessionId: string) {
227
227
  this.#connection = connection;
228
228
  this.#sessionId = sessionId;
229
229
  }
@@ -265,13 +265,13 @@ export class ParallelConnection implements ParallelConnectionInterface {
265
265
  export async function initMainConnection(
266
266
  createRootTarget: () => Promise<void>,
267
267
  onConnectionLost: (message: Platform.UIString.LocalizedString) => void): Promise<void> {
268
- ProtocolClient.InspectorBackend.Connection.setFactory(createMainConnection.bind(null, onConnectionLost));
268
+ ProtocolClient.ConnectionTransport.ConnectionTransport.setFactory(createMainConnection.bind(null, onConnectionLost));
269
269
  await createRootTarget();
270
270
  Host.InspectorFrontendHost.InspectorFrontendHostInstance.connectionReady();
271
271
  }
272
272
 
273
273
  function createMainConnection(onConnectionLost: (message: Platform.UIString.LocalizedString) => void):
274
- ProtocolClient.InspectorBackend.Connection {
274
+ ProtocolClient.ConnectionTransport.ConnectionTransport {
275
275
  if (Root.Runtime.Runtime.isTraceApp()) {
276
276
  return new RehydratingConnection(onConnectionLost);
277
277
  }
@@ -1817,6 +1817,26 @@ export class RequestConditions extends Common.ObjectWrapper.ObjectWrapper<Reques
1817
1817
  this.#conditionsChanged();
1818
1818
  }
1819
1819
 
1820
+ decreasePriority(condition: RequestCondition): void {
1821
+ const index = this.#conditions.indexOf(condition);
1822
+ if (index < 0 || index >= this.#conditions.length - 1) {
1823
+ return;
1824
+ }
1825
+
1826
+ Platform.ArrayUtilities.swap(this.#conditions, index, index + 1);
1827
+ this.dispatchEventToListeners(RequestConditions.Events.REQUEST_CONDITIONS_CHANGED);
1828
+ }
1829
+
1830
+ increasePriority(condition: RequestCondition): void {
1831
+ const index = this.#conditions.indexOf(condition);
1832
+ if (index <= 0) {
1833
+ return;
1834
+ }
1835
+
1836
+ Platform.ArrayUtilities.swap(this.#conditions, index - 1, index);
1837
+ this.dispatchEventToListeners(RequestConditions.Events.REQUEST_CONDITIONS_CHANGED);
1838
+ }
1839
+
1820
1840
  delete(condition: RequestCondition): void {
1821
1841
  const index = this.#conditions.indexOf(condition);
1822
1842
  if (index < 0) {
@@ -63,7 +63,7 @@ export const enum RehydratingConnectionState {
63
63
  REHYDRATED = 3,
64
64
  }
65
65
 
66
- export class RehydratingConnection implements ProtocolClient.InspectorBackend.Connection {
66
+ export class RehydratingConnection implements ProtocolClient.ConnectionTransport.ConnectionTransport {
67
67
  rehydratingConnectionState: RehydratingConnectionState = RehydratingConnectionState.UNINITIALIZED;
68
68
  onDisconnect: ((arg0: string) => void)|null = null;
69
69
  onMessage: ((arg0: Object) => void)|null = null;
@@ -106,11 +106,13 @@ export class RehydratingConnection implements ProtocolClient.InspectorBackend.Co
106
106
 
107
107
  #setupMessagePassing(): void {
108
108
  this.#rehydratingWindow.addEventListener('message', this.#onReceiveHostWindowPayloadBound);
109
- if (!this.#rehydratingWindow.opener) {
109
+ if (this.#rehydratingWindow.opener) {
110
+ this.#rehydratingWindow.opener.postMessage({type: 'REHYDRATING_WINDOW_READY'});
111
+ } else if (this.#rehydratingWindow !== window.top) {
112
+ this.#rehydratingWindow.parent.postMessage({type: 'REHYDRATING_IFRAME_READY'});
113
+ } else {
110
114
  this.#onConnectionLost(i18nString(UIStrings.noHostWindow));
111
- return;
112
115
  }
113
- this.#rehydratingWindow.opener.postMessage({type: 'REHYDRATING_WINDOW_READY'});
114
116
  }
115
117
 
116
118
  /**
@@ -39,7 +39,8 @@ export class Target extends ProtocolClient.InspectorBackend.TargetBase {
39
39
  constructor(
40
40
  targetManager: TargetManager, id: Protocol.Target.TargetID|'main', name: string, type: Type,
41
41
  parentTarget: Target|null, sessionId: string, suspended: boolean,
42
- connection: ProtocolClient.InspectorBackend.Connection|null, targetInfo?: Protocol.Target.TargetInfo) {
42
+ connection: ProtocolClient.ConnectionTransport.ConnectionTransport|null,
43
+ targetInfo?: Protocol.Target.TargetInfo) {
43
44
  const needsNodeJSPatching = type === Type.NODE;
44
45
  super(needsNodeJSPatching, parentTarget, sessionId, connection);
45
46
  this.#targetManager = targetManager;
@@ -209,7 +209,8 @@ export class TargetManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes
209
209
 
210
210
  createTarget(
211
211
  id: Protocol.Target.TargetID|'main', name: string, type: TargetType, parentTarget: Target|null,
212
- sessionId?: string, waitForDebuggerInPage?: boolean, connection?: ProtocolClient.InspectorBackend.Connection,
212
+ sessionId?: string, waitForDebuggerInPage?: boolean,
213
+ connection?: ProtocolClient.ConnectionTransport.ConnectionTransport,
213
214
  targetInfo?: Protocol.Target.TargetInfo): Target {
214
215
  const target = new Target(
215
216
  this, id, name, type, parentTarget, sessionId || '', this.#isSuspended, connection || null, targetInfo);
@@ -146,7 +146,7 @@ export class NodeChildTargetManager extends SDK.SDKModel.SDKModel<void> implemen
146
146
  }
147
147
  }
148
148
 
149
- export class NodeConnection implements ProtocolClient.InspectorBackend.Connection {
149
+ export class NodeConnection implements ProtocolClient.ConnectionTransport.ConnectionTransport {
150
150
  readonly #targetAgent: ProtocolProxyApi.TargetApi;
151
151
  readonly #sessionId: Protocol.Target.SessionID;
152
152
  onMessage: ((arg0: Object|string) => void)|null;
@@ -397,6 +397,7 @@ export class BottomUpRootNode extends Node {
397
397
  const root = this;
398
398
  const startTime = this.startTime;
399
399
  const endTime = this.endTime;
400
+ const idStack: string[] = [];
400
401
  const nodeById = new Map<string, Node>();
401
402
  const selfTimeStack: number[] = [endTime - startTime];
402
403
  const firstNodeStack: boolean[] = [];
@@ -460,6 +461,13 @@ export class BottomUpRootNode extends Node {
460
461
  if (forceGroupIdCallback && eventGroupIdCallback) {
461
462
  id = `${id}-${eventGroupIdCallback(e)}`;
462
463
  }
464
+
465
+ idStack.push(id);
466
+
467
+ // For an event 'X' that contains another event 'X' (resolving to the same node
468
+ // id), we need to measure `totalTime` from the start of the outermost 'X' to
469
+ // its corresponding end. This logic ensures we don't double-count the duration
470
+ // of the inner event.
463
471
  const noNodeOnStack = !totalTimeById.has(id);
464
472
  if (noNodeOnStack) {
465
473
  totalTimeById.set(id, duration);
@@ -468,10 +476,11 @@ export class BottomUpRootNode extends Node {
468
476
  }
469
477
 
470
478
  function onEndEvent(event: Types.Events.Event): void {
471
- let id = generateEventID(event);
472
- if (forceGroupIdCallback && eventGroupIdCallback) {
473
- id = `${id}-${eventGroupIdCallback(event)}`;
479
+ const id = idStack.pop();
480
+ if (!id) {
481
+ return;
474
482
  }
483
+
475
484
  let node = nodeById.get(id);
476
485
  if (!node) {
477
486
  node = new BottomUpNode(root, id, event, false, root);
@@ -484,6 +493,7 @@ export class BottomUpRootNode extends Node {
484
493
  node.totalTime += totalTimeById.get(id) || 0;
485
494
  totalTimeById.delete(id);
486
495
  }
496
+ // TODO: this may be wrong. See the skipped test in TraceTree.test.ts.
487
497
  if (firstNodeStack.length) {
488
498
  node.setHasChildren(true);
489
499
  }
@@ -115,51 +115,6 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
115
115
  }
116
116
 
117
117
  const showPlaceholder = !Boolean(input.mainText);
118
- const renderFooter = (): Lit.LitTemplate => {
119
- // clang-format off
120
- return html`
121
- <div class="tooltip-footer">
122
- ${input.hasTellMeMoreButton ? html`
123
- <devtools-button
124
- title=${lockedString(UIStringsNotTranslate.tellMeMore)}
125
- .jslogContext=${'insights-teaser-tell-me-more'},
126
- .variant=${Buttons.Button.Variant.PRIMARY}
127
- @click=${input.onTellMeMoreClick}
128
- >
129
- <devtools-icon class="lightbulb-icon" name="lightbulb-spark"></devtools-icon>
130
- ${lockedString(UIStringsNotTranslate.tellMeMore)}
131
- </devtools-button>
132
- ` : Lit.nothing}
133
- ${showPlaceholder ? Lit.nothing : html`
134
- <devtools-button
135
- .iconName=${'info'}
136
- .variant=${Buttons.Button.Variant.ICON}
137
- aria-details=${'teaser-info-tooltip-' + input.uuid}
138
- aria-label=${lockedString(UIStringsNotTranslate.learnDataUsage)}
139
- ></devtools-button>
140
- <devtools-tooltip id=${'teaser-info-tooltip-' + input.uuid} variant="rich">
141
- <div class="info-tooltip-text">${lockedString(UIStringsNotTranslate.infoTooltipText)}</div>
142
- <div class="learn-more">
143
- <x-link
144
- class="devtools-link"
145
- title=${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}
146
- href=${DATA_USAGE_URL}
147
- jslog=${VisualLogging.link().track({click: true, keydown:'Enter|Space'}).context('explain.teaser.learn-more')}
148
- >${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}</x-link>
149
- </div>
150
- </devtools-tooltip>
151
- `}
152
- <devtools-checkbox
153
- aria-label=${lockedString(UIStringsNotTranslate.dontShow)}
154
- @change=${input.dontShowChanged}
155
- jslog=${VisualLogging.toggle('explain.teaser.dont-show').track({ change: true })}>
156
- ${lockedString(UIStringsNotTranslate.dontShow)}
157
- </devtools-checkbox>
158
- </div>
159
- `;
160
- // clang-format on
161
- };
162
-
163
118
  // clang-format off
164
119
  render(html`
165
120
  <style>${consoleInsightTeaserStyles}</style>
@@ -185,7 +140,7 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
185
140
  class="loader"
186
141
  style="clip-path: url(${'#clipPath-' + input.uuid});"
187
142
  >
188
- <svg width="100%" height="52">
143
+ <svg width="100%" height="58">
189
144
  <defs>
190
145
  <clipPath id=${'clipPath-' + input.uuid}>
191
146
  <rect x="0" y="0" width="100%" height="12" rx="8"></rect>
@@ -197,10 +152,47 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
197
152
  </div>
198
153
  ` : html`
199
154
  <h2>${input.headerText}</h2>
200
- <div>${input.mainText}</div>
155
+ <div class="main-text">${input.mainText}</div>
201
156
  `
202
157
  }
203
- ${input.isError || input.isSlowGeneration || !showPlaceholder ? renderFooter() : Lit.nothing}
158
+ <div class="tooltip-footer">
159
+ ${input.hasTellMeMoreButton ? html`
160
+ <devtools-button
161
+ title=${lockedString(UIStringsNotTranslate.tellMeMore)}
162
+ .jslogContext=${'insights-teaser-tell-me-more'},
163
+ .variant=${Buttons.Button.Variant.PRIMARY}
164
+ @click=${input.onTellMeMoreClick}
165
+ >
166
+ <devtools-icon class="lightbulb-icon" name="lightbulb-spark"></devtools-icon>
167
+ ${lockedString(UIStringsNotTranslate.tellMeMore)}
168
+ </devtools-button>
169
+ ` : Lit.nothing}
170
+ ${showPlaceholder ? Lit.nothing : html`
171
+ <devtools-button
172
+ .iconName=${'info'}
173
+ .variant=${Buttons.Button.Variant.ICON}
174
+ aria-details=${'teaser-info-tooltip-' + input.uuid}
175
+ .accessibleLabel=${lockedString(UIStringsNotTranslate.learnDataUsage)}
176
+ ></devtools-button>
177
+ <devtools-tooltip id=${'teaser-info-tooltip-' + input.uuid} variant="rich">
178
+ <div class="info-tooltip-text">${lockedString(UIStringsNotTranslate.infoTooltipText)}</div>
179
+ <div class="learn-more">
180
+ <x-link
181
+ class="devtools-link"
182
+ title=${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}
183
+ href=${DATA_USAGE_URL}
184
+ jslog=${VisualLogging.link().track({click: true, keydown:'Enter|Space'}).context('explain.teaser.learn-more')}
185
+ >${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}</x-link>
186
+ </div>
187
+ </devtools-tooltip>
188
+ `}
189
+ <devtools-checkbox
190
+ aria-label=${lockedString(UIStringsNotTranslate.dontShow)}
191
+ @change=${input.dontShowChanged}
192
+ jslog=${VisualLogging.toggle('explain.teaser.dont-show').track({ change: true })}>
193
+ ${lockedString(UIStringsNotTranslate.dontShow)}
194
+ </devtools-checkbox>
195
+ </div>
204
196
  </div>
205
197
  </devtools-tooltip>
206
198
  `, target);
@@ -51,6 +51,19 @@
51
51
  h2 {
52
52
  font: var(--sys-typescale-body4-bold);
53
53
  margin: 0 0 var(--sys-size-3);
54
+ line-clamp: 1;
55
+ -webkit-line-clamp: 1;
56
+ display: -webkit-box;
57
+ -webkit-box-orient: vertical;
58
+ overflow: hidden;
59
+ }
60
+
61
+ .main-text {
62
+ line-clamp: 4;
63
+ -webkit-line-clamp: 4;
64
+ display: -webkit-box;
65
+ -webkit-box-orient: vertical;
66
+ overflow: hidden;
54
67
  }
55
68
 
56
69
  .lightbulb-icon {
@@ -328,7 +328,7 @@ export class LighthousePanel extends UI.Panel.Panel {
328
328
  this.reportSelector.prepend(optionElement);
329
329
  this.refreshToolbarUI();
330
330
  this.renderReport(lighthouseResult);
331
- this.newButton.element.focus();
331
+ (this.auditResultsElement.querySelector('.lh-topbar__url') as HTMLElement | null)?.focus();
332
332
  }
333
333
 
334
334
  private handleDrop(dataTransfer: DataTransfer): void {
@@ -60,7 +60,7 @@ export interface LighthouseRun {
60
60
  export class ProtocolService {
61
61
  private mainSessionId?: string;
62
62
  private rootTargetId?: string;
63
- private parallelConnection?: ProtocolClient.InspectorBackend.Connection;
63
+ private parallelConnection?: ProtocolClient.ConnectionTransport.ConnectionTransport;
64
64
  private lighthouseWorkerPromise?: Promise<Worker>;
65
65
  private lighthouseMessageUpdateCallback?: ((arg0: string) => void);
66
66
  private removeDialogHandler?: () => void;
@@ -99,6 +99,14 @@ const UIStrings = {
99
99
  * @description Message to be announced for a when list item is removed from list widget
100
100
  */
101
101
  learnMore: 'Learn more',
102
+ /**
103
+ * @description Aria label on a button moving an entry up
104
+ */
105
+ increasePriority: 'Increase priority',
106
+ /**
107
+ * @description Aria label on a button moving an entry down
108
+ */
109
+ decreasePriority: 'Decrease priority',
102
110
  } as const;
103
111
  const str_ = i18n.i18n.registerUIStrings('panels/network/RequestConditionsDrawer.ts', UIStrings);
104
112
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -253,6 +261,18 @@ export class RequestConditionsDrawer extends UI.Widget.VBox implements
253
261
  const {enabled, originalOrUpgradedURLPattern, constructorStringOrWildcardURL, wildcardURL} = condition;
254
262
 
255
263
  if (Root.Runtime.hostConfig.devToolsIndividualRequestThrottling?.enabled) {
264
+ const moveUp = (e: Event): void => {
265
+ if (this.manager.requestConditions.conditionsEnabled) {
266
+ e.consume(true);
267
+ this.manager.requestConditions.increasePriority(condition);
268
+ }
269
+ };
270
+ const moveDown = (e: Event): void => {
271
+ if (this.manager.requestConditions.conditionsEnabled) {
272
+ e.consume(true);
273
+ this.manager.requestConditions.decreasePriority(condition);
274
+ }
275
+ };
256
276
  render(
257
277
  // clang-format off
258
278
  html`
@@ -262,17 +282,19 @@ export class RequestConditionsDrawer extends UI.Widget.VBox implements
262
282
  ?checked=${enabled}
263
283
  ?disabled=${!editable || !originalOrUpgradedURLPattern}
264
284
  .jslog=${VisualLogging.toggle().track({ change: true })}>
265
- <devtools-widget
266
- class=conditions-selector
267
- ?disabled=${!editable}
268
- .widgetConfig=${UI.Widget.widgetConfig(
269
- MobileThrottling.NetworkThrottlingSelector.NetworkThrottlingSelectorWidget, {
270
- variant:
271
- MobileThrottling.NetworkThrottlingSelector.NetworkThrottlingSelect.Variant.INDIVIDUAL_REQUEST_CONDITIONS,
272
- jslogContext: 'request-conditions',
273
- onConditionsChanged,
274
- currentConditions: condition.conditions,
275
- })}></devtools-widget>
285
+ <devtools-button
286
+ .iconName=${'arrow-down'}
287
+ .variant=${Buttons.Button.Variant.ICON}
288
+ .title=${i18nString(UIStrings.increasePriority)}
289
+ .jslogContext=${'increase-priority'}
290
+ @click=${moveDown}></devtools-button>
291
+ <devtools-button
292
+ .iconName=${'arrow-up'}
293
+ .variant=${Buttons.Button.Variant.ICON}
294
+ .title=${i18nString(UIStrings.decreasePriority)}
295
+ .jslogContext=${'decrease-priority'}
296
+ @click=${moveUp}>
297
+ </devtools-button>
276
298
  ${originalOrUpgradedURLPattern ? html`
277
299
  <devtools-tooltip variant=rich jslogcontext=url-pattern id=url-pattern-${index}>
278
300
  <div>hash: ${originalOrUpgradedURLPattern.hash}</div>
@@ -309,6 +331,17 @@ export class RequestConditionsDrawer extends UI.Widget.VBox implements
309
331
  aria-details=url-pattern-${index}>
310
332
  ${constructorStringOrWildcardURL}
311
333
  </div>
334
+ <devtools-widget
335
+ class=conditions-selector
336
+ ?disabled=${!editable}
337
+ .widgetConfig=${UI.Widget.widgetConfig(
338
+ MobileThrottling.NetworkThrottlingSelector.NetworkThrottlingSelectorWidget, {
339
+ variant:
340
+ MobileThrottling.NetworkThrottlingSelector.NetworkThrottlingSelect.Variant.INDIVIDUAL_REQUEST_CONDITIONS,
341
+ jslogContext: 'request-conditions',
342
+ onConditionsChanged,
343
+ currentConditions: condition.conditions,
344
+ })}></devtools-widget>
312
345
  <div class=blocked-url-count>${i18nString(UIStrings.dBlocked, {PH1: count})}</div>`,
313
346
  // clang-format on
314
347
  element);