chrome-devtools-frontend 1.0.1704172 → 1.0.1706026

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 (100) hide show
  1. package/AUTHORS +1 -0
  2. package/docs/architecture_of_devtools.md +1 -1
  3. package/docs/cookbook/localization.md +2 -2
  4. package/eslint.config.mjs +1 -0
  5. package/front_end/Images/src/nodejsHex.svg +28 -0
  6. package/front_end/core/common/README.md +4 -3
  7. package/front_end/core/sdk/CPUThrottlingManager.ts +14 -10
  8. package/front_end/core/sdk/DOMModel.ts +65 -20
  9. package/front_end/core/sdk/DebuggerModel.ts +0 -4
  10. package/front_end/core/sdk/PageResourceLoader.ts +12 -11
  11. package/front_end/core/sdk/SourceMap.ts +7 -5
  12. package/front_end/core/sdk/SourceMapFunctionRanges.ts +22 -37
  13. package/front_end/core/sdk/SourceMapScopeChainEntry.ts +3 -3
  14. package/front_end/core/sdk/SourceMapScopesInfo.ts +50 -62
  15. package/front_end/entrypoints/formatter_actions/formatter_actions.ts +18 -0
  16. package/front_end/entrypoints/formatter_worker/Substitute.ts +9 -8
  17. package/front_end/entrypoints/formatter_worker/formatter_worker-entrypoint.ts +9 -4
  18. package/front_end/entrypoints/heap_snapshot_worker/ContextAnalyzer.ts +140 -20
  19. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotLoader.ts +16 -5
  20. package/front_end/entrypoints/inspector_main/nodeIcon.css +1 -1
  21. package/front_end/foundation/Universe.ts +9 -0
  22. package/front_end/generated/InspectorBackendCommands.ts +4 -3
  23. package/front_end/generated/protocol.ts +17 -1
  24. package/front_end/models/ai_assistance/AiConversation.ts +16 -3
  25. package/front_end/models/ai_assistance/skills/accessibility.md +8 -7
  26. package/front_end/models/formatter/FormatterWorkerPool.ts +14 -4
  27. package/front_end/models/javascript_metadata/NativeFunctions.ts +6 -2
  28. package/front_end/models/source_map_scopes/NamesResolver.ts +69 -42
  29. package/front_end/models/source_map_scopes/ScopeChainModel.ts +13 -45
  30. package/front_end/models/source_map_scopes/ScopeChainResolver.ts +101 -0
  31. package/front_end/models/source_map_scopes/source_map_scopes.ts +2 -0
  32. package/front_end/panels/application/BackgroundServiceView.ts +1 -0
  33. package/front_end/panels/application/components/AdsView.ts +6 -6
  34. package/front_end/panels/application/components/BackForwardCacheView.ts +1 -1
  35. package/front_end/panels/console/ConsolePrompt.ts +2 -1
  36. package/front_end/panels/elements/CSSRuleValidator.ts +3 -0
  37. package/front_end/panels/elements/ClassesPaneWidget.ts +4 -1
  38. package/front_end/panels/elements/LayoutPane.ts +17 -20
  39. package/front_end/panels/network/NetworkLogViewColumns.ts +10 -3
  40. package/front_end/panels/network/ShowMoreDetailsWidget.ts +1 -1
  41. package/front_end/panels/security/SecurityPanel.ts +14 -7
  42. package/front_end/panels/sources/BreakpointEditDialog.ts +13 -1
  43. package/front_end/panels/sources/DebuggerPlugin.ts +69 -58
  44. package/front_end/panels/sources/EditingLocationHistoryManager.ts +6 -6
  45. package/front_end/panels/sources/OpenFileQuickOpen.ts +2 -2
  46. package/front_end/panels/sources/Plugin.ts +3 -2
  47. package/front_end/panels/sources/ResourceOriginPlugin.ts +14 -17
  48. package/front_end/panels/sources/ScopeChainSidebarPane.ts +2 -2
  49. package/front_end/panels/sources/SourcesPanel.ts +1 -1
  50. package/front_end/panels/sources/SourcesView.ts +25 -82
  51. package/front_end/panels/sources/TabbedEditorContainer.ts +75 -21
  52. package/front_end/panels/sources/UISourceCodeFrame.ts +22 -13
  53. package/front_end/panels/sources/sourcesView.css +17 -27
  54. package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +1 -0
  55. package/front_end/third_party/chromium/README.chromium +1 -1
  56. package/front_end/third_party/source-map-scopes-codec/README.chromium +2 -2
  57. package/front_end/third_party/source-map-scopes-codec/package/CONTRIBUTING.md +14 -1
  58. package/front_end/third_party/source-map-scopes-codec/package/README.md +8 -6
  59. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts +4 -1
  60. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts.map +1 -1
  61. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts +3 -1
  62. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts.map +1 -1
  63. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts.map +1 -1
  64. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/scopes.d.ts +4 -3
  65. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/scopes.d.ts.map +1 -1
  66. package/front_end/third_party/source-map-scopes-codec/package/deno.json +6 -2
  67. package/front_end/third_party/source-map-scopes-codec/package/package.json +1 -1
  68. package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js +18 -2
  69. package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js.map +1 -1
  70. package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.ts +22 -3
  71. package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js +33 -5
  72. package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js.map +1 -1
  73. package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.ts +41 -5
  74. package/front_end/third_party/source-map-scopes-codec/package/src/codec.js +0 -2
  75. package/front_end/third_party/source-map-scopes-codec/package/src/codec.js.map +1 -1
  76. package/front_end/third_party/source-map-scopes-codec/package/src/codec.ts +4 -3
  77. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js +99 -36
  78. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js.map +1 -1
  79. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.ts +143 -49
  80. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js +3 -1
  81. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js.map +1 -1
  82. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.ts +3 -1
  83. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js +40 -18
  84. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js.map +1 -1
  85. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.ts +51 -21
  86. package/front_end/third_party/source-map-scopes-codec/package/src/scopes.ts +4 -3
  87. package/front_end/third_party/source-map-scopes-codec/package/src/vlq.js +18 -4
  88. package/front_end/third_party/source-map-scopes-codec/package/src/vlq.js.map +1 -1
  89. package/front_end/third_party/source-map-scopes-codec/package/src/vlq.ts +18 -4
  90. package/front_end/ui/comments/CommentOverlayManager.ts +23 -10
  91. package/front_end/ui/components/text_editor/javascript.ts +128 -52
  92. package/front_end/ui/legacy/README.md +12 -12
  93. package/front_end/ui/legacy/SearchableView.ts +125 -74
  94. package/front_end/ui/legacy/components/source_frame/FontView.ts +5 -5
  95. package/front_end/ui/legacy/components/source_frame/ImageView.ts +13 -13
  96. package/front_end/ui/legacy/components/source_frame/ResourceSourceFrame.ts +2 -6
  97. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +3 -2
  98. package/mcp/mcp.ts +1 -0
  99. package/package.json +1 -1
  100. package/front_end/Images/nodeIcon.avif +0 -0
@@ -5,6 +5,7 @@
5
5
 
6
6
  import * as SDK from '../../../core/sdk/sdk.js';
7
7
  import * as Bindings from '../../../models/bindings/bindings.js';
8
+ import * as Formatter from '../../../models/formatter/formatter.js';
8
9
  import * as JavaScriptMetaData from '../../../models/javascript_metadata/javascript_metadata.js';
9
10
  import * as SourceMapScopes from '../../../models/source_map_scopes/source_map_scopes.js';
10
11
  import * as CodeMirror from '../../../third_party/codemirror.next/codemirror.next.js';
@@ -12,9 +13,43 @@ import * as UI from '../../legacy/legacy.js';
12
13
 
13
14
  import {type ArgumentHintsTooltip, closeTooltip, cursorTooltip} from './cursor_tooltip.js';
14
15
 
15
- export function completion(): CodeMirror.Extension {
16
+ export interface CompletionOptions {
17
+ location?: () => Promise<SDK.DebuggerModel.Location|null>;
18
+ }
19
+
20
+ interface EvaluationTarget {
21
+ callFrame?: SDK.DebuggerModel.CallFrame;
22
+ location?: SDK.DebuggerModel.Location;
23
+ }
24
+
25
+ async function resolveEvaluationTarget(options?: CompletionOptions): Promise<EvaluationTarget> {
26
+ const selectedCallFrame = getExecutionContext()?.debuggerModel.selectedCallFrame() ?? undefined;
27
+ if (!options?.location) {
28
+ return {callFrame: selectedCallFrame, location: selectedCallFrame?.location()};
29
+ }
30
+ const location = await options.location() ?? undefined;
31
+ if (selectedCallFrame && location && selectedCallFrame.script.scriptId === location.scriptId &&
32
+ selectedCallFrame.location().lineNumber === location.lineNumber &&
33
+ selectedCallFrame.location().columnNumber === location.columnNumber) {
34
+ return {callFrame: selectedCallFrame, location};
35
+ }
36
+ return {location};
37
+ }
38
+
39
+ /**
40
+ * Whether we can complete properties of expressions on behalf of `target`.
41
+ *
42
+ * If we are not paused at the target location, there is no call frame in which the local variables at that location
43
+ * exist. Evaluating in the global scope instead would silently resolve them to unrelated globals, so we only offer
44
+ * the (statically known) variable names in that case.
45
+ */
46
+ function canCompleteProperties(target: EvaluationTarget): boolean {
47
+ return Boolean(target.callFrame) || !target.location;
48
+ }
49
+
50
+ export function completion(options?: CompletionOptions): CodeMirror.Extension {
16
51
  return CodeMirror.javascript.javascriptLanguage.data.of({
17
- autocomplete: javascriptCompletionSource,
52
+ autocomplete: (cx: CodeMirror.CompletionContext) => javascriptCompletionSource(cx, options),
18
53
  });
19
54
  }
20
55
 
@@ -169,14 +204,15 @@ export function getQueryType(tree: CodeMirror.Tree, pos: number, doc: CodeMirror
169
204
  return {type: QueryType.EXPRESSION};
170
205
  }
171
206
 
172
- export async function javascriptCompletionSource(cx: CodeMirror.CompletionContext):
173
- Promise<CodeMirror.CompletionResult|null> {
207
+ export async function javascriptCompletionSource(
208
+ cx: CodeMirror.CompletionContext, options?: CompletionOptions): Promise<CodeMirror.CompletionResult|null> {
174
209
  const query = getQueryType(CodeMirror.syntaxTree(cx.state), cx.pos, cx.state.doc);
175
210
  if (!query || query.from === undefined && !cx.explicit && query.type === QueryType.EXPRESSION) {
176
211
  return null;
177
212
  }
178
213
 
179
- const script = getExecutionContext()?.debuggerModel.selectedCallFrame()?.script;
214
+ const target = await resolveEvaluationTarget(options);
215
+ const script = target.callFrame?.script ?? target.location?.script() ?? null;
180
216
  if (script &&
181
217
  Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance().pluginManager.hasPluginForScript(script)) {
182
218
  return null;
@@ -186,7 +222,7 @@ export async function javascriptCompletionSource(cx: CodeMirror.CompletionContex
186
222
  let quote: string|undefined = undefined;
187
223
  if (query.type === QueryType.EXPRESSION) {
188
224
  const [scope, global] = await Promise.all([
189
- completeExpressionInScope(),
225
+ completeExpressionInScope(target),
190
226
  completeExpressionGlobal(),
191
227
  ]);
192
228
  if (scope.completions.length) {
@@ -198,6 +234,9 @@ export async function javascriptCompletionSource(cx: CodeMirror.CompletionContex
198
234
  result = global;
199
235
  }
200
236
  } else if (query.type === QueryType.PROPERTY_NAME || query.type === QueryType.PROPERTY_EXPRESSION) {
237
+ if (!canCompleteProperties(target)) {
238
+ return null;
239
+ }
201
240
  const objectExpr = (query.relatedNode as CodeMirror.SyntaxNode).getChild('Expression');
202
241
  if (query.type === QueryType.PROPERTY_EXPRESSION) {
203
242
  quote = query.from === undefined ? '\'' : cx.state.sliceDoc(query.from, query.from + 1);
@@ -205,14 +244,14 @@ export async function javascriptCompletionSource(cx: CodeMirror.CompletionContex
205
244
  if (!objectExpr) {
206
245
  return null;
207
246
  }
208
- result = await completeProperties(
209
- cx.state.sliceDoc(objectExpr.from, objectExpr.to), quote, cx.state.sliceDoc(cx.pos, cx.pos + 1) === ']');
247
+ result = await completeProperties(cx.state.sliceDoc(objectExpr.from, objectExpr.to), quote,
248
+ cx.state.sliceDoc(cx.pos, cx.pos + 1) === ']', target);
210
249
  } else if (query.type === QueryType.POTENTIALLY_RETRIEVING_FROM_MAP) {
211
250
  const potentialMapObject = query.relatedNode;
212
- if (!potentialMapObject) {
251
+ if (!potentialMapObject || !canCompleteProperties(target)) {
213
252
  return null;
214
253
  }
215
- result = await maybeCompleteKeysFromMap(cx.state.sliceDoc(potentialMapObject.from, potentialMapObject.to));
254
+ result = await maybeCompleteKeysFromMap(cx.state.sliceDoc(potentialMapObject.from, potentialMapObject.to), target);
216
255
  } else {
217
256
  return null;
218
257
  }
@@ -236,8 +275,19 @@ async function evaluateExpression(
236
275
  context: SDK.RuntimeModel.ExecutionContext,
237
276
  expression: string,
238
277
  group: string,
278
+ substituteNames = true,
279
+ target?: EvaluationTarget,
239
280
  ): Promise<SDK.RemoteObject.RemoteObject|null> {
240
- const result = await context.evaluateWithSelectedFrameFallback({
281
+ const callFrame = target ? target.callFrame : context.debuggerModel.selectedCallFrame();
282
+ if (substituteNames && callFrame?.script.isJavaScript()) {
283
+ const nameMap = await SourceMapScopes.NamesResolver.allVariablesInCallFrame(
284
+ callFrame, Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance());
285
+ try {
286
+ expression = await Formatter.FormatterWorkerPool.formatterWorkerPool().javaScriptSubstitute(expression, nameMap);
287
+ } catch {
288
+ }
289
+ }
290
+ const evaluationOptions = {
241
291
  expression,
242
292
  objectGroup: group,
243
293
  includeCommandLineAPI: true,
@@ -247,8 +297,9 @@ async function evaluateExpression(
247
297
  throwOnSideEffect: true,
248
298
  timeout: 500,
249
299
  replMode: true,
250
- },
251
- false, false);
300
+ };
301
+ const result =
302
+ callFrame ? await callFrame.evaluate(evaluationOptions) : await context.evaluate(evaluationOptions, false, false);
252
303
  if ('error' in result || result.exceptionDetails || !result.object) {
253
304
  return null;
254
305
  }
@@ -265,7 +316,7 @@ const primitivePrototypes = new Map<string, string>([
265
316
 
266
317
  const maxCacheAge = 30_000;
267
318
 
268
- let cacheInstance: PropertyCache|null = null;
319
+ const cacheByTargetManager = new WeakMap<SDK.TargetManager.TargetManager, PropertyCache>();
269
320
 
270
321
  /**
271
322
  * Store recent collections of property completions. The empty string
@@ -274,15 +325,13 @@ let cacheInstance: PropertyCache|null = null;
274
325
  class PropertyCache {
275
326
  readonly #cache = new Map<string, Promise<CompletionSet>>();
276
327
 
277
- constructor() {
328
+ constructor(targetManager: SDK.TargetManager.TargetManager) {
278
329
  const clear = (): void => this.#cache.clear();
279
- SDK.TargetManager.TargetManager.instance().addModelListener(
280
- SDK.ConsoleModel.ConsoleModel, SDK.ConsoleModel.Events.CommandEvaluated, clear);
330
+ targetManager.addModelListener(SDK.ConsoleModel.ConsoleModel, SDK.ConsoleModel.Events.CommandEvaluated, clear);
281
331
  UI.Context.Context.instance().addFlavorChangeListener(SDK.RuntimeModel.ExecutionContext, clear);
282
- SDK.TargetManager.TargetManager.instance().addModelListener(
283
- SDK.DebuggerModel.DebuggerModel, SDK.DebuggerModel.Events.DebuggerResumed, clear);
284
- SDK.TargetManager.TargetManager.instance().addModelListener(
285
- SDK.DebuggerModel.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, clear);
332
+ targetManager.addModelListener(SDK.DebuggerModel.DebuggerModel, SDK.DebuggerModel.Events.DebuggerResumed, clear);
333
+ targetManager.addModelListener(SDK.DebuggerModel.DebuggerModel, SDK.DebuggerModel.Events.DebuggerPaused, clear);
334
+ targetManager.addModelListener(SDK.DebuggerModel.DebuggerModel, SDK.DebuggerModel.Events.CallFrameSelected, clear);
286
335
  }
287
336
 
288
337
  get(expression: string): Promise<CompletionSet>|undefined {
@@ -299,21 +348,24 @@ class PropertyCache {
299
348
  }
300
349
 
301
350
  static instance(): PropertyCache {
302
- if (!cacheInstance) {
303
- cacheInstance = new PropertyCache();
351
+ const targetManager = SDK.TargetManager.TargetManager.instance();
352
+ let cache = cacheByTargetManager.get(targetManager);
353
+ if (!cache) {
354
+ cache = new PropertyCache(targetManager);
355
+ cacheByTargetManager.set(targetManager, cache);
304
356
  }
305
- return cacheInstance;
357
+ return cache;
306
358
  }
307
359
  }
308
360
 
309
- async function maybeCompleteKeysFromMap(objectVariable: string): Promise<CompletionSet> {
361
+ async function maybeCompleteKeysFromMap(objectVariable: string, target?: EvaluationTarget): Promise<CompletionSet> {
310
362
  const result = new CompletionSet();
311
363
  const context = getExecutionContext();
312
364
  if (!context) {
313
365
  return result;
314
366
  }
315
- const maybeRetrieveKeys =
316
- await evaluateExpression(context, `[...Map.prototype.keys.call(${objectVariable})]`, 'completion');
367
+ const maybeRetrieveKeys = await evaluateExpression(context, `[...Map.prototype.keys.call(${objectVariable})]`,
368
+ 'completion', /* substituteNames */ true, target);
317
369
  if (!maybeRetrieveKeys) {
318
370
  return result;
319
371
  }
@@ -333,6 +385,7 @@ async function completeProperties(
333
385
  expression: string,
334
386
  quoted?: string,
335
387
  hasBracket = false,
388
+ target?: EvaluationTarget,
336
389
  ): Promise<CompletionSet> {
337
390
  const cache = PropertyCache.instance();
338
391
  if (!quoted) {
@@ -345,7 +398,7 @@ async function completeProperties(
345
398
  if (!context) {
346
399
  return new CompletionSet();
347
400
  }
348
- const result = completePropertiesInner(expression, context, quoted, hasBracket);
401
+ const result = completePropertiesInner(expression, context, quoted, hasBracket, target);
349
402
  if (!quoted) {
350
403
  cache.set(expression, result);
351
404
  }
@@ -357,12 +410,13 @@ async function completePropertiesInner(
357
410
  context: SDK.RuntimeModel.ExecutionContext,
358
411
  quoted?: string,
359
412
  hasBracket = false,
413
+ target?: EvaluationTarget,
360
414
  ): Promise<CompletionSet> {
361
415
  const result = new CompletionSet();
362
416
  if (!context) {
363
417
  return result;
364
418
  }
365
- let object = await evaluateExpression(context, expression, 'completion');
419
+ let object = await evaluateExpression(context, expression, 'completion', expression !== 'globalThis', target);
366
420
  if (!object) {
367
421
  return result;
368
422
  }
@@ -378,7 +432,7 @@ async function completePropertiesInner(
378
432
 
379
433
  const toPrototype = primitivePrototypes.get(object.type);
380
434
  if (toPrototype) {
381
- object = await evaluateExpression(context, toPrototype + '.prototype', 'completion');
435
+ object = await evaluateExpression(context, toPrototype + '.prototype', 'completion', /* substituteNames */ false);
382
436
  }
383
437
 
384
438
  const functionType = expression === 'globalThis' ? 'function' : 'method';
@@ -403,23 +457,43 @@ async function completePropertiesInner(
403
457
  return result;
404
458
  }
405
459
 
406
- async function completeExpressionInScope(): Promise<CompletionSet> {
460
+ async function completeExpressionInScope(target: EvaluationTarget): Promise<CompletionSet> {
407
461
  const result = new CompletionSet();
408
- const selectedFrame = getExecutionContext()?.debuggerModel.selectedCallFrame();
409
- if (!selectedFrame) {
462
+ if (target.callFrame) {
463
+ const scopeChain =
464
+ await SourceMapScopes.ScopeChainResolver.ScopeChainResolver.instance().resolveScopeChain(target.callFrame);
465
+ const scopes = await Promise.all(scopeChain.map(scope => scope.object().getAllProperties(false, false)));
466
+ for (const scope of scopes) {
467
+ for (const property of scope.properties || []) {
468
+ if (!property.value && !property.getter) {
469
+ continue;
470
+ }
471
+ result.add({
472
+ label: property.name,
473
+ type: property.value?.type === 'function' ? 'function' : 'variable',
474
+ });
475
+ }
476
+ }
477
+ return result;
478
+ }
479
+
480
+ if (!target.location) {
410
481
  return result;
411
482
  }
412
483
 
413
- const debuggerWorkspaceBinding = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance();
414
- const scopes = await Promise.all(selectedFrame.scopeChain().map(
415
- scope => SourceMapScopes.NamesResolver.resolveScopeInObject(scope, debuggerWorkspaceBinding)
416
- .getAllProperties(false, false)));
417
- for (const scope of scopes) {
418
- for (const property of scope.properties || []) {
419
- result.add({
420
- label: property.name,
421
- type: property.value?.type === 'function' ? 'function' : 'variable',
422
- });
484
+ const mappings = await SourceMapScopes.NamesResolver.allVariablesAtPosition(
485
+ target.location, Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance());
486
+ for (const scope of mappings) {
487
+ const mappedGeneratedNames = new Set(scope.bindings.values());
488
+ for (const [origName, genName] of scope.bindings) {
489
+ if (genName !== null) {
490
+ result.add({label: origName, type: 'variable'});
491
+ }
492
+ }
493
+ for (const genName of scope.generatedNames) {
494
+ if (!mappedGeneratedNames.has(genName)) {
495
+ result.add({label: genName, type: 'variable'});
496
+ }
423
497
  }
424
498
  }
425
499
  return result;
@@ -471,8 +545,8 @@ export async function isExpressionComplete(expression: string): Promise<boolean>
471
545
  return false;
472
546
  }
473
547
 
474
- export function argumentHints(): ArgumentHintsTooltip {
475
- return cursorTooltip(getArgumentHints);
548
+ export function argumentHints(options?: CompletionOptions): ArgumentHintsTooltip {
549
+ return cursorTooltip((state, pos) => getArgumentHints(state, pos, options));
476
550
  }
477
551
 
478
552
  export function closeArgumentsHintsTooltip(
@@ -486,8 +560,8 @@ export function closeArgumentsHintsTooltip(
486
560
  return true;
487
561
  }
488
562
 
489
- async function getArgumentHints(
490
- state: CodeMirror.EditorState, pos: number): Promise<(() => CodeMirror.TooltipView)|null> {
563
+ async function getArgumentHints(state: CodeMirror.EditorState, pos: number,
564
+ options?: CompletionOptions): Promise<(() => CodeMirror.TooltipView)|null> {
491
565
  const node = CodeMirror.syntaxTree(state).resolveInner(pos).enterUnfinishedNodesBefore(pos);
492
566
 
493
567
  if (node.name !== 'ArgList') {
@@ -497,7 +571,7 @@ async function getArgumentHints(
497
571
  if (!callee) {
498
572
  return null;
499
573
  }
500
- const argumentList = await getArgumentsForExpression(callee, state.doc);
574
+ const argumentList = await getArgumentsForExpression(callee, state.doc, options);
501
575
  if (!argumentList) {
502
576
  return null;
503
577
  }
@@ -516,14 +590,15 @@ async function getArgumentHints(
516
590
  return () => tooltipBuilder(argumentList, argumentIndex);
517
591
  }
518
592
 
519
- async function getArgumentsForExpression(
520
- callee: CodeMirror.SyntaxNode, doc: CodeMirror.Text): Promise<string[][]|null> {
593
+ async function getArgumentsForExpression(callee: CodeMirror.SyntaxNode, doc: CodeMirror.Text,
594
+ options?: CompletionOptions): Promise<string[][]|null> {
521
595
  const context = getExecutionContext();
522
596
  if (!context) {
523
597
  return null;
524
598
  }
599
+ const target = await resolveEvaluationTarget(options);
525
600
  const expression = doc.sliceString(callee.from, callee.to);
526
- const result = await evaluateExpression(context, expression, 'argumentsHint');
601
+ const result = await evaluateExpression(context, expression, 'argumentsHint', /* substituteNames */ true, target);
527
602
  if (result?.type !== 'function') {
528
603
  return null;
529
604
  }
@@ -532,7 +607,8 @@ async function getArgumentsForExpression(
532
607
  if (!first || callee.name !== 'MemberExpression') {
533
608
  return null;
534
609
  }
535
- return await evaluateExpression(context, doc.sliceString(first.from, first.to), 'argumentsHint');
610
+ return await evaluateExpression(context, doc.sliceString(first.from, first.to), 'argumentsHint',
611
+ /* substituteNames */ true, target);
536
612
  };
537
613
  return await getArgumentsForFunctionValue(result, objGetter, expression)
538
614
  .finally(() => context.runtimeModel.releaseObjectGroup('argumentsHint'));
@@ -73,11 +73,11 @@ UI.ActionRegistration.registerActionExtension({
73
73
  bindings: [
74
74
  {
75
75
  shortcut: 'Ctrl+E',
76
- platform: UI.ActionRegistration.Platforms.WindowsLinux,
76
+ platform: UI.ActionRegistration.Platforms.WINDOWS_LINUX,
77
77
  },
78
78
  {
79
79
  shortcut: 'Meta+E',
80
- platform: UI.ActionRegistration.Platforms.Mac,
80
+ platform: UI.ActionRegistration.Platforms.MAC,
81
81
  },
82
82
  ],
83
83
  });
@@ -87,7 +87,7 @@ UI.ActionRegistration.registerActionExtension({
87
87
 
88
88
  #### Context types
89
89
  The `contextTypes` property determines the context under which the action is available.
90
- A context is defined as set 'flavors' or classes, which usually represent views, that are added and removed to the context as the user interacts with the application (e.g when the user moves across views).
90
+ A context is defined as set of 'flavors' or classes, which usually represent views, that are added and removed to the context as the user interacts with the application (e.g when the user moves across views).
91
91
  (See [`UI.Context`](./Context.js)).
92
92
  Therefore, an action can only be triggered when one of its respective context types is visible.
93
93
  These flavors can be retrieved invoking the method `flavors` inside the class `UI.Context.Context`.
@@ -97,10 +97,10 @@ In this case, the action will always be available, regardless of which context i
97
97
 
98
98
  #### Key bindings
99
99
 
100
- The `bindings` property defines a `platform` and a `keybindSets` properties along with the keyboard shortcut itself.
100
+ The `bindings` property defines `platform` and `keybindSets` properties along with the `shortcut` property containing the actual keyboard shortcut.
101
101
  These two extra properties add more conditions (additional to the ones introduced by the `contextTypes` property discussed before) that need to be fulfilled to trigger a particular action.
102
102
 
103
- - `platform` refers to the OS on which DevTools is running and can be either `mac` or `windows,linux`.
103
+ - `platform` refers to the OS on which DevTools is running and can be either `MAC`, `WINDOWS_LINUX` or `WINDOWS`. (See [`UI.ActionRegistration`](./ActionRegistration.ts)).
104
104
  - `keybindSets` refers to the selected shortcut preset, which can be changed in `settings -> shortcuts -> “Match shortcuts from preset”`.
105
105
  A key binding will be used when the selected preset matches any of the keybind sets declared by the binding.
106
106
 
@@ -125,16 +125,16 @@ UI.ActionRegistration.registerActionExtension({
125
125
  contextTypes: undefined,
126
126
  bindings: [
127
127
  {
128
- platform: 'windows,linux',
128
+ platform: UI.ActionRegistration.Platforms.WINDOWS_LINUX,
129
129
  shortcut: 'Esc',
130
130
  },
131
131
  ],
132
132
  });
133
133
  ```
134
134
 
135
- These two key bindings both allocate the same key for the `windows, linux` platform (the first one is global across platforms) in the `ElementsPanel` context (the second one is global across context types) and both are global across keybind sets.
135
+ These two key bindings both allocate the same key for the `WINDOWS_LINUX` platform (the first one is global across platforms) in the `ElementsPanel` context (the second one is global across context types) and both are global across keybind sets.
136
136
 
137
- If key bindings were declared such that **at least one** of the three variables (`platform, contextTypes` and `keybindSets`) doesn't overlap, then no duplication would occur.
137
+ If key bindings were declared such that **at least one** of the three variables (`platform`, `contextTypes` and `keybindSets`) doesn't overlap, then no duplication would occur.
138
138
  For example, the following is **not** a form of duplication:
139
139
 
140
140
  ```ts
@@ -147,7 +147,7 @@ UI.ActionRegistration.registerActionExtension({
147
147
  bindings: [
148
148
  {
149
149
  shortcut: 'Esc',
150
- keybindSets: ['devToolsDefault'],
150
+ keybindSets: [UI.ActionRegistration.KeybindSet.DEVTOOLS_DEFAULT],
151
151
  },
152
152
  ],
153
153
  });
@@ -160,12 +160,12 @@ UI.ActionRegistration.registerActionExtension({
160
160
  contextTypes: undefined,
161
161
  bindings: [
162
162
  {
163
- platform: 'windows,linux',
163
+ platform: UI.ActionRegistration.Platforms.WINDOWS_LINUX,
164
164
  shortcut: 'Esc',
165
- keybindSets: ['vsCode'],
165
+ keybindSets: [UI.ActionRegistration.KeybindSet.VS_CODE],
166
166
  },
167
167
  ],
168
168
  });
169
169
  ```
170
170
 
171
- In this case, they keybindings are declared for different keybind sets and thus do not result in duplcation.
171
+ In this case, the keybindings are declared for different keybind sets and thus do not result in duplication.