chrome-devtools-frontend 1.0.1624409 → 1.0.1625079

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 (86) hide show
  1. package/.agents/skills/foundation-test-migration/SKILL.md +3 -3
  2. package/front_end/core/host/AidaClient.ts +6 -5
  3. package/front_end/core/host/AidaClientTypes.ts +3 -1
  4. package/front_end/core/host/DispatchHttpRequestClient.ts +6 -3
  5. package/front_end/core/platform/api/HostRuntime.ts +3 -0
  6. package/front_end/core/platform/browser/HostRuntime.ts +10 -0
  7. package/front_end/core/platform/node/HostRuntime.ts +10 -0
  8. package/front_end/core/root/Runtime.ts +6 -5
  9. package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +6 -2
  10. package/front_end/models/ai_code_completion/AiCodeCompletion.ts +2 -3
  11. package/front_end/models/ai_code_generation/AiCodeGeneration.ts +2 -3
  12. package/front_end/models/javascript_metadata/NativeFunctions.js +4 -0
  13. package/front_end/models/trace/insights/DuplicatedJavaScript.ts +4 -0
  14. package/front_end/models/trace/insights/FontDisplay.ts +4 -0
  15. package/front_end/models/trace/insights/LegacyJavaScript.ts +4 -0
  16. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +8 -4
  17. package/front_end/panels/ai_assistance/components/ChatMessage.ts +7 -5
  18. package/front_end/panels/ai_assistance/components/ChatView.ts +2 -2
  19. package/front_end/panels/elements/StylePropertyTreeElement.ts +2 -2
  20. package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +6 -1
  21. package/front_end/panels/elements/StylesSidebarPane.ts +12 -1
  22. package/front_end/panels/elements/stylePropertiesTreeOutline.css +5 -1
  23. package/front_end/panels/emulation/DeviceModeToolbar.ts +144 -128
  24. package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +12 -4
  25. package/front_end/panels/timeline/components/insights/DuplicatedJavaScript.ts +4 -0
  26. package/front_end/panels/timeline/components/insights/FontDisplay.ts +4 -0
  27. package/front_end/panels/timeline/components/insights/LegacyJavaScript.ts +4 -0
  28. package/front_end/third_party/chromium/README.chromium +1 -1
  29. package/front_end/third_party/lighthouse/README.chromium +2 -2
  30. package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +5176 -5104
  31. package/front_end/third_party/lighthouse/locales/ar-XB.json +72 -36
  32. package/front_end/third_party/lighthouse/locales/ar.json +72 -36
  33. package/front_end/third_party/lighthouse/locales/bg.json +72 -36
  34. package/front_end/third_party/lighthouse/locales/ca.json +72 -36
  35. package/front_end/third_party/lighthouse/locales/cs.json +72 -36
  36. package/front_end/third_party/lighthouse/locales/da.json +74 -38
  37. package/front_end/third_party/lighthouse/locales/de.json +72 -36
  38. package/front_end/third_party/lighthouse/locales/el.json +73 -37
  39. package/front_end/third_party/lighthouse/locales/en-GB.json +74 -38
  40. package/front_end/third_party/lighthouse/locales/en-US.json +245 -17
  41. package/front_end/third_party/lighthouse/locales/en-XL.json +245 -17
  42. package/front_end/third_party/lighthouse/locales/es-419.json +72 -36
  43. package/front_end/third_party/lighthouse/locales/es.json +73 -37
  44. package/front_end/third_party/lighthouse/locales/fi.json +72 -36
  45. package/front_end/third_party/lighthouse/locales/fil.json +74 -38
  46. package/front_end/third_party/lighthouse/locales/fr.json +162 -126
  47. package/front_end/third_party/lighthouse/locales/he.json +74 -38
  48. package/front_end/third_party/lighthouse/locales/hi.json +73 -37
  49. package/front_end/third_party/lighthouse/locales/hr.json +72 -36
  50. package/front_end/third_party/lighthouse/locales/hu.json +73 -37
  51. package/front_end/third_party/lighthouse/locales/id.json +74 -38
  52. package/front_end/third_party/lighthouse/locales/it.json +72 -36
  53. package/front_end/third_party/lighthouse/locales/ja.json +72 -36
  54. package/front_end/third_party/lighthouse/locales/ko.json +72 -36
  55. package/front_end/third_party/lighthouse/locales/lt.json +72 -36
  56. package/front_end/third_party/lighthouse/locales/lv.json +72 -36
  57. package/front_end/third_party/lighthouse/locales/nl.json +73 -37
  58. package/front_end/third_party/lighthouse/locales/no.json +72 -36
  59. package/front_end/third_party/lighthouse/locales/pl.json +72 -36
  60. package/front_end/third_party/lighthouse/locales/pt-PT.json +72 -36
  61. package/front_end/third_party/lighthouse/locales/pt.json +74 -38
  62. package/front_end/third_party/lighthouse/locales/ro.json +72 -36
  63. package/front_end/third_party/lighthouse/locales/ru.json +72 -36
  64. package/front_end/third_party/lighthouse/locales/sk.json +72 -36
  65. package/front_end/third_party/lighthouse/locales/sl.json +72 -36
  66. package/front_end/third_party/lighthouse/locales/sr-Latn.json +73 -37
  67. package/front_end/third_party/lighthouse/locales/sr.json +73 -37
  68. package/front_end/third_party/lighthouse/locales/sv.json +75 -39
  69. package/front_end/third_party/lighthouse/locales/ta.json +73 -37
  70. package/front_end/third_party/lighthouse/locales/te.json +72 -36
  71. package/front_end/third_party/lighthouse/locales/th.json +73 -37
  72. package/front_end/third_party/lighthouse/locales/tr.json +72 -36
  73. package/front_end/third_party/lighthouse/locales/uk.json +72 -36
  74. package/front_end/third_party/lighthouse/locales/vi.json +74 -38
  75. package/front_end/third_party/lighthouse/locales/zh-HK.json +72 -36
  76. package/front_end/third_party/lighthouse/locales/zh-TW.json +74 -38
  77. package/front_end/third_party/lighthouse/locales/zh.json +75 -39
  78. package/front_end/third_party/lighthouse/report/bundle.js +2 -1
  79. package/front_end/third_party/lighthouse/report-assets/report-generator.mjs +1 -1
  80. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +6 -2
  81. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +4 -1
  82. package/front_end/ui/legacy/SuggestBox.ts +1 -0
  83. package/front_end/ui/legacy/TextPrompt.ts +2 -1
  84. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +328 -47
  85. package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
  86. package/package.json +9 -8
@@ -5,6 +5,7 @@
5
5
  import * as Common from '../../../core/common/common.js';
6
6
  import * as Host from '../../../core/host/host.js';
7
7
  import * as i18n from '../../../core/i18n/i18n.js';
8
+ import * as Root from '../../../core/root/root.js';
8
9
  import * as AiCodeCompletion from '../../../models/ai_code_completion/ai_code_completion.js';
9
10
  import * as AiCodeGeneration from '../../../models/ai_code_generation/ai_code_generation.js';
10
11
  import * as PanelCommon from '../../../panels/common/common.js';
@@ -158,8 +159,11 @@ export class AiCodeCompletionProvider {
158
159
  return;
159
160
  }
160
161
  this.#aiCodeCompletion = new AiCodeCompletion.AiCodeCompletion.AiCodeCompletion(
161
- {aidaClient: this.#aidaClient}, this.#aiCodeCompletionConfig.panel, undefined,
162
- this.#aiCodeCompletionConfig.completionContext.stopSequences);
162
+ {
163
+ aidaClient: this.#aidaClient,
164
+ serverSideLoggingEnabled: !Root.Runtime.hostConfig.aidaAvailability?.disallowLogging,
165
+ },
166
+ this.#aiCodeCompletionConfig.panel, undefined, this.#aiCodeCompletionConfig.completionContext.stopSequences);
163
167
  this.#aiCodeCompletionConfig.onFeatureEnabled();
164
168
  }
165
169
 
@@ -119,7 +119,10 @@ export class AiCodeGenerationProvider {
119
119
  if (this.#aiCodeGeneration) {
120
120
  return;
121
121
  }
122
- this.#aiCodeGeneration = new AiCodeGeneration.AiCodeGeneration.AiCodeGeneration({aidaClient: this.#aidaClient});
122
+ this.#aiCodeGeneration = new AiCodeGeneration.AiCodeGeneration.AiCodeGeneration({
123
+ aidaClient: this.#aidaClient,
124
+ serverSideLoggingEnabled: !Root.Runtime.hostConfig.aidaAvailability?.disallowLogging,
125
+ });
123
126
  this.#editor?.dispatch({
124
127
  effects:
125
128
  [this.#generationTeaserCompartment.reconfigure([aiCodeGenerationTeaserExtension(this.#generationTeaser)])],
@@ -345,6 +345,7 @@ export interface Suggestion {
345
345
  };
346
346
  hideGhostText?: boolean;
347
347
  iconElement?: HTMLElement;
348
+ disableAcceptSuggestionOnStopCharacters?: boolean;
348
349
  }
349
350
 
350
351
  export type Suggestions = Suggestion[];
@@ -598,7 +598,8 @@ export class TextPrompt extends Common.ObjectWrapper.ObjectWrapper<EventTypes> i
598
598
 
599
599
  private acceptSuggestionOnStopCharacters(key: string): boolean {
600
600
  if (!this.currentSuggestion || !this.queryRange || key.length !== 1 ||
601
- !this.completionStopCharacters?.includes(key)) {
601
+ !this.completionStopCharacters?.includes(key) ||
602
+ this.currentSuggestion.disableAcceptSuggestionOnStopCharacters) {
602
603
  return false;
603
604
  }
604
605
 
@@ -152,18 +152,236 @@ interface NodeChildren {
152
152
  export interface ObjectTreeOptions {
153
153
  readonly propertiesMode: ObjectPropertiesMode;
154
154
  readonly readOnly: boolean;
155
+ readonly expansionTracker?: ObjectTreeExpansionTracker;
156
+ }
157
+
158
+ type KeyTypes = {
159
+ [K in keyof Required<NodeChildren>]: Key<Required<NodeChildren>[K][0]>;
160
+ };
161
+
162
+ type Key<T> = T extends ObjectTreeNode ? string : T extends ArrayGroupTreeNode ? ArrayGroupRange : never;
163
+ interface TrackingKey {
164
+ type: keyof KeyTypes;
165
+ key: KeyTypes[keyof KeyTypes];
166
+ }
167
+
168
+ class NodeExpansionLog {
169
+ properties = new Map<string, NodeExpansionLog>();
170
+ internalProperties = new Map<string, NodeExpansionLog>();
171
+ arrayRanges = new Map<string, NodeExpansionLog>();
172
+ accessors = new Map<string, NodeExpansionLog>();
173
+
174
+ remove(key: TrackingKey): boolean {
175
+ return this[key.type].delete(NodeExpansionLog.#serializeKey(key));
176
+ }
177
+
178
+ get(key: TrackingKey): NodeExpansionLog|undefined {
179
+ return this[key.type].get(NodeExpansionLog.#serializeKey(key));
180
+ }
181
+
182
+ getOrInsert(key: TrackingKey): NodeExpansionLog {
183
+ const map = this[key.type];
184
+ const serializedKey = NodeExpansionLog.#serializeKey(key);
185
+ const log = map.get(serializedKey) ?? new NodeExpansionLog();
186
+ if (!map.has(serializedKey)) {
187
+ map.set(serializedKey, log);
188
+ }
189
+ return log;
190
+ }
191
+
192
+ clear(type: keyof KeyTypes): void {
193
+ this[type].clear();
194
+ }
195
+
196
+ clearMissing(type: keyof KeyTypes, seen: TrackingKey[]): void {
197
+ const seenSet = new Set(seen.map(NodeExpansionLog.#serializeKey));
198
+ const map = this[type];
199
+ for (const key of map.keys()) {
200
+ if (!seenSet.has(key)) {
201
+ map.delete(key);
202
+ }
203
+ }
204
+ }
205
+
206
+ get empty(): boolean {
207
+ return this.properties.size === 0 && this.internalProperties.size === 0 && this.arrayRanges.size === 0 &&
208
+ this.accessors.size === 0;
209
+ }
210
+
211
+ static #serializeKey(key: TrackingKey): string {
212
+ if (typeof key.key === 'string') {
213
+ return `${key.type}:${key.key}`;
214
+ }
215
+ return `${key.type}:${key.key.fromIndex}-${key.key.toIndex}`;
216
+ }
217
+ }
218
+
219
+ export class ObjectTreeExpansionTracker {
220
+ #log: NodeExpansionLog|null = null;
221
+
222
+ /**
223
+ * For nodes physically nested within a parent's [[Prototype]] internal property, the node's
224
+ * parent property points to the logical parent (skipping the [[Prototype]] node). This helper
225
+ * finds that skipped [[Prototype]] node if it contains the given node.
226
+ */
227
+ static #protoParent(node: ObjectTreeNodeBase): ObjectTreeNode|undefined {
228
+ if (!(node instanceof ObjectTreeNode)) {
229
+ return undefined;
230
+ }
231
+ return node.parent?.children?.internalProperties?.find(
232
+ p => p.name === '[[Prototype]]' && p.children?.properties?.includes(node));
233
+ }
234
+
235
+ static #keyType(node: ObjectTreeNodeBase): keyof NodeChildren|null {
236
+ if (node instanceof ObjectTreeNode) {
237
+ if (node.parent?.children?.properties?.includes(node)) {
238
+ return 'properties';
239
+ }
240
+ if (node.parent?.children?.internalProperties?.includes(node)) {
241
+ return 'internalProperties';
242
+ }
243
+ if (node.parent?.children?.accessors?.includes(node)) {
244
+ return 'accessors';
245
+ }
246
+ const proto = ObjectTreeExpansionTracker.#protoParent(node);
247
+ if (proto) {
248
+ return 'properties';
249
+ }
250
+ }
251
+ if (node instanceof ArrayGroupTreeNode && node.parent?.children?.arrayRanges?.includes(node)) {
252
+ return 'arrayRanges';
253
+ }
254
+ return null;
255
+ }
256
+
257
+ static #key(type: keyof KeyTypes, node: ObjectTreeNodeBase): TrackingKey|null {
258
+ switch (type) {
259
+ case 'arrayRanges':
260
+ return node instanceof ArrayGroupTreeNode ? {type, key: node.range} : null;
261
+ default:
262
+ return node instanceof ObjectTreeNode ? {type, key: node.name} : null;
263
+ }
264
+ }
265
+
266
+ clear(): void {
267
+ this.#log = null;
268
+ }
269
+
270
+ async #apply(log: NodeExpansionLog, node: ObjectTreeNodeBase): Promise<void> {
271
+ const apply = async<KeyType extends keyof KeyTypes>(type: KeyType): Promise<void> => {
272
+ const nodes = node.children?.[type];
273
+ if (!nodes) {
274
+ log.clear(type);
275
+ return;
276
+ }
277
+ const seen: TrackingKey[] = [];
278
+ for (const childNode of nodes) {
279
+ const key = ObjectTreeExpansionTracker.#key(type, childNode);
280
+ if (!key) {
281
+ continue;
282
+ }
283
+ const childLog = log.get(key);
284
+ if (childLog) {
285
+ await this.#apply(childLog, childNode);
286
+ seen.push(key);
287
+ }
288
+ }
289
+ log.clearMissing(type, seen);
290
+ };
291
+
292
+ node.expanded = true;
293
+ await node.populateChildrenIfNeeded();
294
+ await apply('properties');
295
+ await apply('internalProperties');
296
+ await apply('arrayRanges');
297
+ await apply('accessors');
298
+ }
299
+
300
+ async apply(node: ObjectTree): Promise<void> {
301
+ if (this.#log) {
302
+ return await this.#apply(this.#log, node);
303
+ }
304
+ }
305
+
306
+ static * #path(node: ObjectTreeNodeBase|undefined): Generator<TrackingKey> {
307
+ if (!node) {
308
+ return;
309
+ }
310
+
311
+ const proto = ObjectTreeExpansionTracker.#protoParent(node);
312
+ if (proto) {
313
+ yield* this.#path(proto);
314
+ } else {
315
+ yield* this.#path(node.parent);
316
+ }
317
+
318
+ const keyType = this.#keyType(node);
319
+ const key = keyType && ObjectTreeExpansionTracker.#key(keyType, node);
320
+ if (key) {
321
+ yield key;
322
+ }
323
+ }
324
+
325
+ collapse(node: ObjectTreeNodeBase): void {
326
+ if (!this.#log) {
327
+ return;
328
+ }
329
+ if (node instanceof ObjectTree) {
330
+ this.#log = null;
331
+ return;
332
+ }
333
+
334
+ let lastKey;
335
+ let parent: NodeExpansionLog|null = null;
336
+ let log: NodeExpansionLog = this.#log;
337
+ for (const key of ObjectTreeExpansionTracker.#path(node)) {
338
+ lastKey = key;
339
+ parent = log;
340
+ const nextLog = log.get(key);
341
+ if (!nextLog) {
342
+ return;
343
+ }
344
+ log = nextLog;
345
+ }
346
+
347
+ if (lastKey && parent) {
348
+ parent.remove(lastKey);
349
+ }
350
+ }
351
+
352
+ expand(node: ObjectTreeNodeBase): void {
353
+ if (!this.#log) {
354
+ this.#log = new NodeExpansionLog();
355
+ }
356
+ let log: NodeExpansionLog = this.#log;
357
+ for (const key of ObjectTreeExpansionTracker.#path(node)) {
358
+ log = log.getOrInsert(key);
359
+ }
360
+ }
155
361
  }
156
362
 
157
363
  export abstract class ObjectTreeNodeBase extends Common.ObjectWrapper.ObjectWrapper<ObjectTreeNodeBase.EventTypes> {
158
364
  #children?: NodeChildren;
159
365
  protected filter: {includeNullOrUndefinedValues: boolean, regex: RegExp|null}|null = null;
160
366
  protected extraProperties: ObjectTreeNode[] = [];
161
- expanded = false;
367
+ #expanded = false;
162
368
 
163
369
  constructor(readonly parent: ObjectTreeNodeBase|undefined, protected readonly options: ObjectTreeOptions) {
164
370
  super();
165
371
  this.filter = parent?.filter ?? null;
166
372
  }
373
+ get expanded(): boolean {
374
+ return this.#expanded;
375
+ }
376
+
377
+ set expanded(val: boolean) {
378
+ if (val) {
379
+ this.options.expansionTracker?.expand(this);
380
+ } else {
381
+ this.options.expansionTracker?.collapse(this);
382
+ }
383
+ this.#expanded = val;
384
+ }
167
385
 
168
386
  get readOnly(): boolean {
169
387
  return this.options.readOnly;
@@ -253,11 +471,22 @@ export abstract class ObjectTreeNodeBase extends Common.ObjectWrapper.ObjectWrap
253
471
  return this.#children;
254
472
  }
255
473
 
474
+ #populatePromise?: Promise<NodeChildren>;
256
475
  async populateChildrenIfNeeded(): Promise<NodeChildren> {
257
- if (!this.#children) {
258
- this.#children = await this.populateChildrenIfNeededImpl();
476
+ if (this.#children) {
477
+ return this.#children;
259
478
  }
260
- return this.#children;
479
+ if (!this.#populatePromise) {
480
+ this.#populatePromise = this.populateChildrenIfNeededImpl()
481
+ .then(children => {
482
+ this.#children = children;
483
+ return children;
484
+ })
485
+ .finally(() => {
486
+ this.#populatePromise = undefined;
487
+ });
488
+ }
489
+ return await this.#populatePromise;
261
490
  }
262
491
 
263
492
  protected async populateChildrenIfNeededImpl(): Promise<NodeChildren> {
@@ -271,9 +500,12 @@ export abstract class ObjectTreeNodeBase extends Common.ObjectWrapper.ObjectWrap
271
500
  if (this.arrayLength > ARRAY_LOAD_THRESHOLD) {
272
501
  const ranges = await arrayRangeGroups(object, 0, this.arrayLength - 1);
273
502
  const arrayRanges = ranges?.ranges.map(
274
- ([fromIndex, toIndex, count]) => new ArrayGroupTreeNode(
275
- object, {fromIndex, toIndex, count}, effectiveParent,
276
- {readOnly: this.readOnly, propertiesMode: this.propertiesMode}));
503
+ ([fromIndex, toIndex, count]) =>
504
+ new ArrayGroupTreeNode(object, {fromIndex, toIndex, count}, effectiveParent, {
505
+ readOnly: this.readOnly,
506
+ propertiesMode: this.propertiesMode,
507
+ expansionTracker: this.options.expansionTracker
508
+ }));
277
509
  if (!arrayRanges) {
278
510
  return {};
279
511
  }
@@ -282,15 +514,18 @@ export abstract class ObjectTreeNodeBase extends Common.ObjectWrapper.ObjectWrap
282
514
  await SDK.RemoteObject.RemoteObject.loadFromObjectPerProto(
283
515
  this.object, true /* generatePreview */, true /* nonIndexedPropertiesOnly */);
284
516
 
285
- const properties = objectProperties?.map(
286
- p => new ObjectTreeNode(
287
- p, effectiveParent,
288
- {readOnly: this.readOnly, propertiesMode: ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED}));
289
-
290
- const internalProperties = objectInternalProperties?.map(
291
- p => new ObjectTreeNode(
292
- p, effectiveParent,
293
- {readOnly: this.readOnly, propertiesMode: ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED}));
517
+ const properties = objectProperties?.map(p => new ObjectTreeNode(p, effectiveParent, {
518
+ readOnly: this.readOnly,
519
+ propertiesMode: ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
520
+ expansionTracker: this.options.expansionTracker
521
+ }));
522
+
523
+ const internalProperties =
524
+ objectInternalProperties?.map(p => new ObjectTreeNode(p, effectiveParent, {
525
+ readOnly: this.readOnly,
526
+ propertiesMode: ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
527
+ expansionTracker: this.options.expansionTracker
528
+ }));
294
529
  return {arrayRanges, properties, internalProperties};
295
530
  }
296
531
 
@@ -307,18 +542,21 @@ export abstract class ObjectTreeNodeBase extends Common.ObjectWrapper.ObjectWrap
307
542
  break;
308
543
  }
309
544
 
310
- const properties = objectProperties?.map(
311
- p => new ObjectTreeNode(
312
- p, effectiveParent,
313
- {readOnly: this.readOnly, propertiesMode: ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED}));
545
+ const properties = objectProperties?.map(p => new ObjectTreeNode(p, effectiveParent, {
546
+ readOnly: this.readOnly,
547
+ propertiesMode: ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
548
+ expansionTracker: this.options.expansionTracker
549
+ }));
314
550
  properties?.push(...this.extraProperties);
315
551
  properties?.sort(ObjectPropertiesSection.compareProperties);
316
- const accessors = properties && ObjectTreeNodeBase.getGettersAndSetters(properties);
317
-
318
- const internalProperties = objectInternalProperties?.map(
319
- p => new ObjectTreeNode(
320
- p, effectiveParent,
321
- {readOnly: this.readOnly, propertiesMode: ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED}));
552
+ const accessors = properties && ObjectTreeNodeBase.getGettersAndSetters(properties, this.options);
553
+
554
+ const internalProperties =
555
+ objectInternalProperties?.map(p => new ObjectTreeNode(p, effectiveParent, {
556
+ readOnly: this.readOnly,
557
+ propertiesMode: ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
558
+ expansionTracker: this.options.expansionTracker
559
+ }));
322
560
  return {properties, internalProperties, accessors};
323
561
  }
324
562
 
@@ -336,26 +574,34 @@ export abstract class ObjectTreeNodeBase extends Common.ObjectWrapper.ObjectWrap
336
574
  }
337
575
 
338
576
  addExtraProperties(...properties: SDK.RemoteObject.RemoteObjectProperty[]): void {
339
- this.extraProperties.push(...properties.map(
340
- p => new ObjectTreeNode(
341
- p, this, {readOnly: this.readOnly, propertiesMode: ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED})));
577
+ this.extraProperties.push(...properties.map(p => new ObjectTreeNode(p, this, {
578
+ readOnly: this.readOnly,
579
+ propertiesMode: ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
580
+ expansionTracker: this.options.expansionTracker
581
+ })));
342
582
  }
343
583
 
344
- static getGettersAndSetters(properties: ObjectTreeNode[]): ObjectTreeNode[] {
584
+ static getGettersAndSetters(properties: ObjectTreeNode[], options: ObjectTreeOptions): ObjectTreeNode[] {
345
585
  const gettersAndSetters = [];
346
586
  for (const property of properties) {
347
587
  if (property.property.isOwn) {
348
588
  if (property.property.getter) {
349
589
  const getterProperty = new SDK.RemoteObject.RemoteObjectProperty(
350
590
  'get ' + property.property.name, property.property.getter, false);
351
- gettersAndSetters.push(new ObjectTreeNode(
352
- getterProperty, property.parent, {propertiesMode: property.propertiesMode, readOnly: property.readOnly}));
591
+ gettersAndSetters.push(new ObjectTreeNode(getterProperty, property.parent, {
592
+ propertiesMode: property.propertiesMode,
593
+ readOnly: property.readOnly,
594
+ expansionTracker: options.expansionTracker
595
+ }));
353
596
  }
354
597
  if (property.property.setter) {
355
598
  const setterProperty = new SDK.RemoteObject.RemoteObjectProperty(
356
599
  'set ' + property.property.name, property.property.setter, false);
357
- gettersAndSetters.push(new ObjectTreeNode(
358
- setterProperty, property.parent, {propertiesMode: property.propertiesMode, readOnly: property.readOnly}));
600
+ gettersAndSetters.push(new ObjectTreeNode(setterProperty, property.parent, {
601
+ propertiesMode: property.propertiesMode,
602
+ readOnly: property.readOnly,
603
+ expansionTracker: options.expansionTracker
604
+ }));
359
605
  }
360
606
  }
361
607
  }
@@ -388,12 +634,18 @@ export class ObjectTree extends ObjectTreeNodeBase {
388
634
  }
389
635
  }
390
636
 
391
- class ArrayGroupTreeNode extends ObjectTreeNodeBase {
637
+ interface ArrayGroupRange {
638
+ fromIndex: number;
639
+ toIndex: number;
640
+ count: number;
641
+ }
642
+
643
+ export class ArrayGroupTreeNode extends ObjectTreeNodeBase {
392
644
  readonly #object: SDK.RemoteObject.RemoteObject;
393
- readonly #range: {fromIndex: number, toIndex: number, count: number};
645
+ readonly #range: ArrayGroupRange;
394
646
  constructor(
395
- object: SDK.RemoteObject.RemoteObject, range: {fromIndex: number, toIndex: number, count: number},
396
- parent: ObjectTreeNodeBase, options: ObjectTreeOptions) {
647
+ object: SDK.RemoteObject.RemoteObject, range: ArrayGroupRange, parent: ObjectTreeNodeBase,
648
+ options: ObjectTreeOptions) {
397
649
  super(parent, options);
398
650
  this.#object = object;
399
651
  this.#range = range;
@@ -403,9 +655,11 @@ class ArrayGroupTreeNode extends ObjectTreeNodeBase {
403
655
  if (this.#range.count > ArrayGroupingTreeElement.bucketThreshold) {
404
656
  const ranges = await arrayRangeGroups(this.object, this.#range.fromIndex, this.#range.toIndex);
405
657
  const arrayRanges = ranges?.ranges.map(
406
- ([fromIndex, toIndex, count]) => new ArrayGroupTreeNode(
407
- this.object, {fromIndex, toIndex, count}, this,
408
- {readOnly: this.readOnly, propertiesMode: this.propertiesMode}));
658
+ ([fromIndex, toIndex, count]) => new ArrayGroupTreeNode(this.object, {fromIndex, toIndex, count}, this, {
659
+ readOnly: this.readOnly,
660
+ propertiesMode: this.propertiesMode,
661
+ expansionTracker: this.options.expansionTracker
662
+ }));
409
663
  return {arrayRanges};
410
664
  }
411
665
 
@@ -421,11 +675,14 @@ class ArrayGroupTreeNode extends ObjectTreeNodeBase {
421
675
  const allProperties =
422
676
  await arrayFragment.getAllProperties(false /* accessorPropertiesOnly */, true /* generatePreview */);
423
677
  arrayFragment.release();
424
- const properties = allProperties.properties?.map(
425
- p => new ObjectTreeNode(p, this, {propertiesMode: this.propertiesMode, readOnly: this.readOnly}));
678
+ const properties = allProperties.properties?.map(p => new ObjectTreeNode(p, this, {
679
+ propertiesMode: this.propertiesMode,
680
+ readOnly: this.readOnly,
681
+ expansionTracker: this.options.expansionTracker
682
+ }));
426
683
  properties?.push(...this.extraProperties);
427
684
  properties?.sort(ObjectPropertiesSection.compareProperties);
428
- const accessors = properties && ObjectTreeNodeBase.getGettersAndSetters(properties);
685
+ const accessors = properties && ObjectTreeNodeBase.getGettersAndSetters(properties, this.options);
429
686
  return {properties, accessors};
430
687
  }
431
688
 
@@ -433,7 +690,7 @@ class ArrayGroupTreeNode extends ObjectTreeNodeBase {
433
690
  return this.#range.fromIndex === this.#range.toIndex;
434
691
  }
435
692
 
436
- get range(): {fromIndex: number, toIndex: number, count: number} {
693
+ get range(): ArrayGroupRange {
437
694
  return this.#range;
438
695
  }
439
696
 
@@ -559,8 +816,10 @@ export class ObjectPropertiesSection extends UI.TreeOutline.TreeOutlineInShadow
559
816
  object: SDK.RemoteObject.RemoteObject, title?: string|Element|null, linkifier?: Components.Linkifier.Linkifier,
560
817
  showOverflow?: boolean, editable = true) {
561
818
  super();
562
- this.root = new ObjectTree(
563
- object, {readOnly: !editable, propertiesMode: ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED});
819
+ this.root = new ObjectTree(object, {
820
+ readOnly: !editable,
821
+ propertiesMode: ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
822
+ });
564
823
  if (!showOverflow) {
565
824
  this.setHideOverflow(true);
566
825
  }
@@ -995,15 +1254,20 @@ export class RootElement extends UI.TreeOutline.TreeElement {
995
1254
  this.toggleOnClick = true;
996
1255
  this.listItemElement.classList.add('object-properties-section-root-element');
997
1256
  this.listItemElement.addEventListener('contextmenu', this.onContextMenu.bind(this), false);
1257
+ if (object.expanded) {
1258
+ this.expand();
1259
+ }
998
1260
  }
999
1261
 
1000
1262
  override onexpand(): void {
1263
+ this.object.expanded = true;
1001
1264
  if (this.treeOutline) {
1002
1265
  this.treeOutline.element.classList.add('expanded');
1003
1266
  }
1004
1267
  }
1005
1268
 
1006
1269
  override oncollapse(): void {
1270
+ this.object.expanded = false;
1007
1271
  if (this.treeOutline) {
1008
1272
  this.treeOutline.element.classList.remove('expanded');
1009
1273
  }
@@ -1350,7 +1614,11 @@ export class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
1350
1614
  this.maxNumPropertiesToShow = InitialVisibleChildrenLimit;
1351
1615
  this.listItemElement.addEventListener('contextmenu', this.contextMenuFired.bind(this), false);
1352
1616
  this.listItemElement.dataset.objectPropertyNameForTest = property.name;
1617
+ this.updateExpandable();
1353
1618
  this.setExpandRecursively(property.name !== '[[Prototype]]');
1619
+ if (property.expanded) {
1620
+ this.expand();
1621
+ }
1354
1622
  }
1355
1623
 
1356
1624
  static async populate(
@@ -1523,10 +1791,12 @@ export class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
1523
1791
  }
1524
1792
 
1525
1793
  override onexpand(): void {
1794
+ this.property.expanded = true;
1526
1795
  this.#widget.expanded = true;
1527
1796
  }
1528
1797
 
1529
1798
  override oncollapse(): void {
1799
+ this.property.expanded = false;
1530
1800
  this.#widget.expanded = false;
1531
1801
  }
1532
1802
 
@@ -1750,6 +2020,9 @@ export class ArrayGroupingTreeElement extends UI.TreeOutline.TreeElement {
1750
2020
  this.#child.addEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, this.onpopulate, this);
1751
2021
  this.toggleOnClick = true;
1752
2022
  this.linkifier = linkifier;
2023
+ if (child.expanded) {
2024
+ this.expand();
2025
+ }
1753
2026
  }
1754
2027
 
1755
2028
  static async populate(
@@ -1773,6 +2046,14 @@ export class ArrayGroupingTreeElement extends UI.TreeOutline.TreeElement {
1773
2046
  ObjectPropertyTreeElement.populateWithProperties(treeNode, children, false, false, linkifier);
1774
2047
  }
1775
2048
 
2049
+ override onexpand(): void {
2050
+ this.#child.expanded = true;
2051
+ }
2052
+
2053
+ override oncollapse(): void {
2054
+ this.#child.expanded = false;
2055
+ }
2056
+
1776
2057
  override async onpopulate(): Promise<void> {
1777
2058
  this.removeChildren();
1778
2059
  await ObjectPropertyTreeElement.populate(this, this.#child, false, false, this.linkifier);
@@ -2340,6 +2340,7 @@ export const knownContextValues = new Set([
2340
2340
  'lighthouse.audit.aria-treeitem-name',
2341
2341
  'lighthouse.audit.aria-valid-attr',
2342
2342
  'lighthouse.audit.aria-valid-attr-value',
2343
+ 'lighthouse.audit.autocomplete-valid',
2343
2344
  'lighthouse.audit.baseline',
2344
2345
  'lighthouse.audit.bf-cache',
2345
2346
  'lighthouse.audit.bootup-time',
@@ -2447,6 +2448,7 @@ export const knownContextValues = new Set([
2447
2448
  'lighthouse.audit.offscreen-images',
2448
2449
  'lighthouse.audit.origin-isolation',
2449
2450
  'lighthouse.audit.paste-preventing-inputs',
2451
+ 'lighthouse.audit.presentation-role-conflict',
2450
2452
  'lighthouse.audit.prioritize-lcp-image',
2451
2453
  'lighthouse.audit.redirects',
2452
2454
  'lighthouse.audit.redirects-http',
@@ -2461,6 +2463,7 @@ export const knownContextValues = new Set([
2461
2463
  'lighthouse.audit.skip-link',
2462
2464
  'lighthouse.audit.speed-index',
2463
2465
  'lighthouse.audit.structured-data',
2466
+ 'lighthouse.audit.svg-img-alt',
2464
2467
  'lighthouse.audit.tabindex',
2465
2468
  'lighthouse.audit.table-duplicate-name',
2466
2469
  'lighthouse.audit.table-fake-caption',
package/package.json CHANGED
@@ -79,7 +79,7 @@
79
79
  "mocha": "11.7.5",
80
80
  "ora": "9.0.0",
81
81
  "postcss": "8.5.6",
82
- "puppeteer-core": "24.30.0",
82
+ "puppeteer-core": "24.42.0",
83
83
  "rollup": "4.22.4",
84
84
  "rollup-plugin-sourcemaps2": "0.5.4",
85
85
  "sinon": "21.0.0",
@@ -97,12 +97,13 @@
97
97
  "js-rouge": "3.2.0"
98
98
  },
99
99
  "overrides": {
100
- "baseline-browser-mapping": "2.8.25",
101
- "electron-to-chromium": "1.5.248",
102
- "caniuse-lite": "1.0.30001754",
103
- "stylelint": {
104
- "flat-cache": "6.1.12"
105
- }
100
+ "electron-to-chromium": "1.5.335",
101
+ "bare-os": "3.9.0",
102
+ "bare-stream": "2.13.0",
103
+ "tar-stream": "3.1.5",
104
+ "socks": "2.8.7",
105
+ "ip-address": "10.1.0",
106
+ "basic-ftp": "5.2.2"
106
107
  },
107
- "version": "1.0.1624409"
108
+ "version": "1.0.1625079"
108
109
  }