chrome-devtools-frontend 1.0.1643099 → 1.0.1643855

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 (45) hide show
  1. package/eslint.config.mjs +3 -1
  2. package/extension-api/ExtensionAPI.d.ts +83 -12
  3. package/front_end/core/host/UserMetrics.ts +0 -1
  4. package/front_end/core/root/ExperimentNames.ts +0 -1
  5. package/front_end/core/sdk/ConsoleModel.ts +4 -0
  6. package/front_end/core/sdk/NetworkRequest.ts +12 -0
  7. package/front_end/core/sdk/SourceMap.ts +15 -18
  8. package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +0 -2
  9. package/front_end/entrypoints/greendev_floaty/greendev_floaty.ts +0 -2
  10. package/front_end/entrypoints/main/MainImpl.ts +0 -6
  11. package/front_end/models/ai_assistance/AiAgent2.ts +1 -0
  12. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +22 -16
  13. package/front_end/models/ai_assistance/agents/AiAgent.ts +19 -6
  14. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +5 -5
  15. package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +1 -94
  16. package/front_end/models/ai_assistance/agents/NetworkAgent.ts +25 -0
  17. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +22 -0
  18. package/front_end/models/ai_assistance/agents/StorageAgent.ts +54 -1
  19. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +1 -2
  20. package/front_end/models/ai_assistance/agents/StylingAgent.ts +5 -0
  21. package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +4 -10
  22. package/front_end/models/ai_assistance/tools/Tool.ts +6 -0
  23. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +6 -9
  24. package/front_end/models/bindings/DefaultScriptMapping.ts +2 -1
  25. package/front_end/models/bindings/SymbolizedError.ts +45 -35
  26. package/front_end/models/extensions/ExtensionAPI.ts +138 -47
  27. package/front_end/models/har/Importer.ts +1 -0
  28. package/front_end/models/source_map_scopes/FunctionCodeResolver.ts +12 -2
  29. package/front_end/models/stack_trace/DetailedErrorStackParser.ts +44 -51
  30. package/front_end/models/stack_trace/StackTrace.ts +7 -0
  31. package/front_end/models/stack_trace/StackTraceImpl.ts +13 -4
  32. package/front_end/models/stack_trace/StackTraceModel.ts +9 -8
  33. package/front_end/panels/accessibility/AccessibilitySidebarView.ts +2 -1
  34. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +2 -1
  35. package/front_end/panels/application/ApplicationPanelSidebar.ts +39 -0
  36. package/front_end/panels/application/ApplicationPanelTreeElement.ts +39 -0
  37. package/front_end/panels/application/CookieItemsView.ts +2 -2
  38. package/front_end/panels/application/resourcesSidebar.css +11 -0
  39. package/front_end/panels/console/SymbolizedErrorWidget.ts +10 -7
  40. package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +1 -0
  41. package/front_end/panels/sources/SourcesPanel.ts +2 -1
  42. package/front_end/ui/legacy/StackedPane.ts +229 -0
  43. package/front_end/ui/legacy/ViewManager.ts +59 -169
  44. package/front_end/ui/legacy/legacy.ts +3 -1
  45. package/package.json +1 -1
@@ -62,57 +62,56 @@ export function parseRawFramesFromErrorStack(stack: string): RawFrame[]|null {
62
62
  let evalOrigin: RawFrame|undefined;
63
63
 
64
64
  const openParenIndex = lineContent.indexOf(' (');
65
+ let location = '';
65
66
  if (lineContent.endsWith(')') && openParenIndex !== -1) {
66
67
  functionName = lineContent.substring(0, openParenIndex).trim();
67
- let location = lineContent.substring(openParenIndex + 2, lineContent.length - 1);
68
-
69
- if (location.startsWith('eval at ')) {
70
- isEval = true;
71
- const commaIndex = location.lastIndexOf(', ');
72
- let evalOriginStr = location;
73
- if (commaIndex !== -1) {
74
- evalOriginStr = location.substring(0, commaIndex);
75
- location = location.substring(commaIndex + 2);
76
- } else {
77
- location = '';
78
- }
79
-
80
- if (evalOriginStr.startsWith('eval at ')) {
81
- evalOriginStr = evalOriginStr.substring(8);
82
- }
83
- const innerOpenParen = evalOriginStr.indexOf(' (');
84
- let evalFunctionName = evalOriginStr;
85
- let evalLocation = '';
86
- if (innerOpenParen !== -1) {
87
- evalFunctionName = evalOriginStr.substring(0, innerOpenParen).trim();
88
- evalLocation = evalOriginStr.substring(innerOpenParen + 2, evalOriginStr.length - 1);
89
- evalOrigin = parseRawFramesFromErrorStack(` at ${evalFunctionName} (${evalLocation})`)?.[0];
90
- } else {
91
- evalOrigin = parseRawFramesFromErrorStack(` at ${evalFunctionName}`)?.[0];
92
- }
68
+ location = lineContent.substring(openParenIndex + 2, lineContent.length - 1);
69
+ } else {
70
+ location = lineContent;
71
+ }
72
+
73
+ if (location.startsWith('eval at ')) {
74
+ isEval = true;
75
+ const commaIndex = location.lastIndexOf(', ');
76
+ let evalOriginStr = location;
77
+ if (commaIndex !== -1) {
78
+ evalOriginStr = location.substring(0, commaIndex);
79
+ location = location.substring(commaIndex + 2);
80
+ } else {
81
+ location = '';
93
82
  }
94
83
 
95
- if (location.startsWith('index ')) {
96
- promiseIndex = parseInt(location.substring(6), 10);
97
- url = '';
98
- } else if (location === '<anonymous>' || location === 'native') {
99
- url = '';
100
- } else if (location.includes(':wasm-function[')) {
101
- isWasm = true;
102
- const wasmMatch = /^(.*):wasm-function\[(\d+)\]:(0x[0-9a-fA-F]+)$/.exec(location);
103
- if (wasmMatch) {
104
- url = wasmMatch[1];
105
- wasmFunctionIndex = parseInt(wasmMatch[2], 10);
106
- columnNumber = parseInt(wasmMatch[3], 16);
107
- }
84
+ if (evalOriginStr.startsWith('eval at ')) {
85
+ evalOriginStr = evalOriginStr.substring(8);
86
+ }
87
+ const innerOpenParen = evalOriginStr.indexOf(' (');
88
+ let evalFunctionName = evalOriginStr;
89
+ let evalLocation = '';
90
+ if (innerOpenParen !== -1) {
91
+ evalFunctionName = evalOriginStr.substring(0, innerOpenParen).trim();
92
+ evalLocation = evalOriginStr.substring(innerOpenParen + 2, evalOriginStr.length - 1);
93
+ evalOrigin = parseRawFramesFromErrorStack(` at ${evalFunctionName} (${evalLocation})`)?.[0];
108
94
  } else {
109
- const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(location);
110
- url = splitResult.url;
111
- lineNumber = splitResult.lineNumber ?? -1;
112
- columnNumber = splitResult.columnNumber ?? -1;
95
+ evalOrigin = parseRawFramesFromErrorStack(` at ${evalFunctionName}`)?.[0];
113
96
  }
114
- } else {
115
- const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(lineContent);
97
+ }
98
+
99
+ if (location.startsWith('index ')) {
100
+ promiseIndex = parseInt(location.substring(6), 10);
101
+ url = '';
102
+ } else if (location === '<anonymous>' || location === 'native') {
103
+ url = '';
104
+ } else if (location.includes(':wasm-function[')) {
105
+ isWasm = true;
106
+ const wasmMatch = /^(.*):wasm-function\[(\d+)\]:(0x[0-9a-fA-F]+)$/.exec(location);
107
+ if (wasmMatch) {
108
+ url = wasmMatch[1];
109
+ wasmFunctionIndex = parseInt(wasmMatch[2], 10);
110
+ columnNumber = parseInt(wasmMatch[3], 16);
111
+ lineNumber = 0;
112
+ }
113
+ } else if (location) {
114
+ const splitResult = Common.ParsedURL.ParsedURL.splitLineAndColumn(location);
116
115
  url = splitResult.url;
117
116
  lineNumber = splitResult.lineNumber ?? -1;
118
117
  columnNumber = splitResult.columnNumber ?? -1;
@@ -181,13 +180,7 @@ export function parseMessage(stack: string): string {
181
180
  export function augmentRawFramesWithScriptIds(
182
181
  rawFrames: RawFrame[], protocolStackTrace: Protocol.Runtime.StackTrace): void {
183
182
  function augmentFrame(rawFrame: RawFrame): void {
184
- const isWasm = rawFrame.isWasm;
185
183
  const protocolFrame = protocolStackTrace.callFrames.find(frame => {
186
- if (isWasm) {
187
- // The parser parses Wasm offsets into the `columnNumber` field. The `lineNumber` is always -1.
188
- // In the protocol trace, the `lineNumber` is 0 (for Wasm) and `columnNumber` is the bytecode offset.
189
- return rawFrame.url === frame.url && rawFrame.columnNumber === frame.columnNumber;
190
- }
191
184
  return rawFrame.url === frame.url && rawFrame.lineNumber === frame.lineNumber &&
192
185
  rawFrame.columnNumber === frame.columnNumber;
193
186
  });
@@ -48,6 +48,13 @@ export interface Frame {
48
48
  * Whether the corresponding raw frame is JS or WASM.
49
49
  */
50
50
  readonly isWasm?: boolean;
51
+ /**
52
+ * Whether this frame is an inlined frame. Used by SymbolizedErrorWidget
53
+ * to render the translated name (i.e. `name`) for inlined frames, and
54
+ * the physical name (i.e. `rawName`) for normal frames to preserve existing
55
+ * behavior.
56
+ */
57
+ readonly isInline?: boolean;
51
58
  }
52
59
 
53
60
  export interface ParsedErrorStackFrame extends Frame {
@@ -89,11 +89,12 @@ export class FrameImpl implements StackTrace.StackTrace.Frame {
89
89
  readonly missingDebugInfo?: StackTrace.StackTrace.MissingDebugInfo;
90
90
  readonly rawName?: string;
91
91
  readonly isWasm?: boolean;
92
+ readonly isInline?: boolean;
92
93
 
93
- constructor(
94
- url: string|undefined, uiSourceCode: Workspace.UISourceCode.UISourceCode|undefined, name: string|undefined,
95
- line: number, column: number, missingDebugInfo?: StackTrace.StackTrace.MissingDebugInfo, rawName?: string,
96
- isWasm?: boolean) {
94
+ constructor(url: string|undefined, uiSourceCode: Workspace.UISourceCode.UISourceCode|undefined,
95
+ name: string|undefined, line: number, column: number,
96
+ missingDebugInfo?: StackTrace.StackTrace.MissingDebugInfo, rawName?: string, isWasm?: boolean,
97
+ isInline?: boolean) {
97
98
  this.url = url;
98
99
  this.uiSourceCode = uiSourceCode;
99
100
  this.name = name;
@@ -102,6 +103,7 @@ export class FrameImpl implements StackTrace.StackTrace.Frame {
102
103
  this.missingDebugInfo = missingDebugInfo;
103
104
  this.rawName = rawName;
104
105
  this.isWasm = isWasm;
106
+ this.isInline = isInline;
105
107
  }
106
108
  }
107
109
 
@@ -197,6 +199,9 @@ export class ParsedErrorStackFrameImpl implements StackTrace.StackTrace.ParsedEr
197
199
  get isWasm(): boolean|undefined {
198
200
  return this.#frame.isWasm;
199
201
  }
202
+ get isInline(): boolean|undefined {
203
+ return this.#frame.isInline;
204
+ }
200
205
  get wasmModuleName(): string|undefined {
201
206
  return this.#parsedFrameInfo?.wasmModuleName;
202
207
  }
@@ -291,6 +296,10 @@ export class DebuggableFrameImpl implements StackTrace.StackTrace.DebuggableFram
291
296
  return this.#frame.isWasm;
292
297
  }
293
298
 
299
+ get isInline(): boolean|undefined {
300
+ return this.#frame.isInline;
301
+ }
302
+
294
303
  get sdkFrame(): SDK.DebuggerModel.CallFrame {
295
304
  return this.#sdkFrame;
296
305
  }
@@ -211,10 +211,11 @@ export class StackTraceModel extends SDK.SDKModel.SDKModel<unknown> {
211
211
  let i = 0;
212
212
  let evalI = 0;
213
213
  for (const node of fragment.node.getCallStack()) {
214
- node.frames = uiFrames[i++].map(
215
- frame => new FrameImpl(
216
- frame.url, frame.uiSourceCode, frame.name, frame.line, frame.column, frame.missingDebugInfo,
217
- node.rawFrame.functionName, node.rawFrame.isWasm));
214
+ const group = uiFrames[i++];
215
+ node.frames =
216
+ group.map((frame, index) => new FrameImpl(frame.url, frame.uiSourceCode, frame.name, frame.line, frame.column,
217
+ frame.missingDebugInfo, node.rawFrame.functionName,
218
+ node.rawFrame.isWasm, index < group.length - 1));
218
219
 
219
220
  if (node.parsedFrameInfo?.evalOrigin) {
220
221
  node.evalOrigin = evalOrigins[evalI++];
@@ -253,10 +254,10 @@ async function translateEvalOrigin(
253
254
  rawFrame: RawFrame, rawFramesToUIFrames: TranslateRawFrames,
254
255
  target: SDK.Target.Target): Promise<EvalOrigin|undefined> {
255
256
  const uiFrames = await rawFramesToUIFrames([rawFrame], target);
256
- const frames = uiFrames[0].map(
257
- frame => new FrameImpl(
258
- frame.url, frame.uiSourceCode, frame.name, frame.line, frame.column, frame.missingDebugInfo,
259
- rawFrame.functionName, rawFrame.isWasm));
257
+ const group = uiFrames[0];
258
+ const frames = group.map((frame, index) => new FrameImpl(frame.url, frame.uiSourceCode, frame.name, frame.line,
259
+ frame.column, frame.missingDebugInfo, rawFrame.functionName,
260
+ rawFrame.isWasm, index < group.length - 1));
260
261
 
261
262
  let parentEvalOrigin: EvalOrigin|undefined;
262
263
  if (rawFrame.parsedFrameInfo?.evalOrigin) {
@@ -33,7 +33,7 @@ export class AccessibilitySidebarView extends UI.Widget.VBox {
33
33
  #node: SDK.DOMModel.DOMNode|null;
34
34
  #axNode: SDK.AccessibilityModel.AccessibilityNode|null;
35
35
  private skipNextPullNode: boolean;
36
- private readonly sidebarPaneStack: UI.View.ViewLocation;
36
+ private readonly sidebarPaneStack: UI.ViewManager.StackLocation;
37
37
  private readonly ariaSubPane: ARIAAttributesPane;
38
38
  private readonly axNodeSubPane: AXNodeSubPane;
39
39
  private readonly sourceOrderSubPane: SourceOrderPane;
@@ -159,6 +159,7 @@ export class AccessibilitySidebarView extends UI.Widget.VBox {
159
159
 
160
160
  private updateToggle(): void {
161
161
  const isToggled = this.toggleAction.toggled();
162
+ this.sidebarPaneStack.notifyVisibilityChanged(isToggled);
162
163
  // eslint-disable-next-line @devtools/no-lit-render-outside-of-view
163
164
  render(
164
165
  html`
@@ -2115,7 +2115,8 @@ export class ActionDelegate implements UI.ActionRegistration.ActionDelegate {
2115
2115
  case 'drjones.network-panel-context':
2116
2116
  case 'drjones.performance-panel-context':
2117
2117
  case 'drjones.sources-floating-button':
2118
- case 'drjones.sources-panel-context': {
2118
+ case 'drjones.sources-panel-context':
2119
+ case 'ai-assistance.storage-floating-button': {
2119
2120
  void (async () => {
2120
2121
  const view = UI.ViewManager.ViewManager.instance().view(
2121
2122
  AiAssistancePanel.panelName,
@@ -40,6 +40,7 @@ import * as Platform from '../../core/platform/platform.js';
40
40
  import * as Root from '../../core/root/root.js';
41
41
  import * as SDK from '../../core/sdk/sdk.js';
42
42
  import * as Protocol from '../../generated/protocol.js';
43
+ import * as AiAssistance from '../../models/ai_assistance/ai_assistance.js';
43
44
  import * as LegacyWrapper from '../../ui/components/legacy_wrapper/legacy_wrapper.js';
44
45
  import {createIcon} from '../../ui/kit/kit.js';
45
46
  import * as SourceFrame from '../../ui/legacy/components/source_frame/source_frame.js';
@@ -1762,9 +1763,29 @@ export class DOMStorageTreeElement extends ApplicationPanelTreeElement {
1762
1763
  return false;
1763
1764
  }
1764
1765
 
1766
+ /**
1767
+ * Resolves the DOM storage partition context (`localStorage` or `sessionStorage`)
1768
+ * associated with this tree element for AI assistance.
1769
+ */
1770
+ #getStorageItem(): AiAssistance.StorageItem.StorageItem|null {
1771
+ const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
1772
+ const mainPageOrigin =
1773
+ target?.inspectedURL() ? Common.ParsedURL.ParsedURL.extractOrigin(target.inspectedURL()) : '';
1774
+ if (!mainPageOrigin || !this.domStorage.storageKey) {
1775
+ return null;
1776
+ }
1777
+ const origin = SDK.StorageKeyManager.parseStorageKey(this.domStorage.storageKey).origin;
1778
+ const storageType = this.domStorage.isLocalStorage ? 'localStorage' : 'sessionStorage';
1779
+ return new AiAssistance.StorageItem.DOMStorageItem(mainPageOrigin, origin, this.domStorage.storageKey, storageType);
1780
+ }
1781
+
1765
1782
  override onattach(): void {
1766
1783
  super.onattach();
1767
1784
  this.listItemElement.addEventListener('contextmenu', this.handleContextMenuEvent.bind(this), true);
1785
+ const storageItem = this.#getStorageItem();
1786
+ if (storageItem) {
1787
+ this.createAiButton(storageItem);
1788
+ }
1768
1789
  }
1769
1790
 
1770
1791
  private handleContextMenuEvent(event: MouseEvent): void {
@@ -1851,9 +1872,27 @@ export class CookieTreeElement extends ApplicationPanelTreeElement {
1851
1872
  return this.#cookieDomain;
1852
1873
  }
1853
1874
 
1875
+ /**
1876
+ * Resolves the cookie domain security context associated with this tree element
1877
+ * for AI assistance.
1878
+ */
1879
+ #getStorageItem(): AiAssistance.StorageItem.StorageItem|null {
1880
+ const primaryTarget = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
1881
+ const mainPageOrigin =
1882
+ primaryTarget?.inspectedURL() ? Common.ParsedURL.ParsedURL.extractOrigin(primaryTarget.inspectedURL()) : '';
1883
+ if (!mainPageOrigin || !this.#cookieDomain) {
1884
+ return null;
1885
+ }
1886
+ return new AiAssistance.StorageItem.CookieItem(mainPageOrigin, this.#cookieDomain);
1887
+ }
1888
+
1854
1889
  override onattach(): void {
1855
1890
  super.onattach();
1856
1891
  this.listItemElement.addEventListener('contextmenu', this.handleContextMenuEvent.bind(this), true);
1892
+ const storageItem = this.#getStorageItem();
1893
+ if (storageItem) {
1894
+ this.createAiButton(storageItem);
1895
+ }
1857
1896
  }
1858
1897
 
1859
1898
  private handleContextMenuEvent(event: Event): void {
@@ -2,15 +2,24 @@
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
+ /* eslint-disable @devtools/no-lit-render-outside-of-view */
6
+
7
+ import '../../ui/components/buttons/buttons.js';
8
+
5
9
  import * as Common from '../../core/common/common.js';
6
10
  import type * as Platform from '../../core/platform/platform.js';
11
+ import * as AiAssistance from '../../models/ai_assistance/ai_assistance.js';
7
12
  import * as UI from '../../ui/legacy/legacy.js';
13
+ import * as Lit from '../../ui/lit/lit.js';
8
14
 
9
15
  import type {ResourcesPanel} from './ResourcesPanel.js';
10
16
 
17
+ const {html} = Lit;
18
+
11
19
  export class ApplicationPanelTreeElement extends UI.TreeOutline.TreeElement {
12
20
  protected readonly resourcesPanel: ResourcesPanel;
13
21
  private customItemURL?: Platform.DevToolsPath.UrlString;
22
+ protected aiButtonContainer?: HTMLElement;
14
23
 
15
24
  constructor(resourcesPanel: ResourcesPanel, title: string, expandable: boolean, jslogContext: string) {
16
25
  super(title, expandable, jslogContext);
@@ -56,6 +65,36 @@ export class ApplicationPanelTreeElement extends UI.TreeOutline.TreeElement {
56
65
  showView(view: UI.Widget.AnyWidget|null): void {
57
66
  this.resourcesPanel.showView(view);
58
67
  }
68
+
69
+ protected createAiButton(storageItem: AiAssistance.StorageItem.StorageItem): void {
70
+ const STORAGE_FLOATING_BUTTON_ACTION_ID = 'ai-assistance.storage-floating-button';
71
+ const actionRegistry = UI.ActionRegistry.ActionRegistry.instance();
72
+ if (!actionRegistry.hasAction(STORAGE_FLOATING_BUTTON_ACTION_ID)) {
73
+ return;
74
+ }
75
+ const action = actionRegistry.getAction(STORAGE_FLOATING_BUTTON_ACTION_ID);
76
+ if (!this.aiButtonContainer) {
77
+ this.aiButtonContainer = this.listItemElement.createChild('span', 'ai-button-container');
78
+ const icon = AiAssistance.AiUtils.getIconName();
79
+ const onClick = (ev: Event): void => {
80
+ ev.stopPropagation();
81
+ UI.Context.Context.instance().setFlavor(AiAssistance.StorageItem.StorageItem, storageItem);
82
+ void action.execute();
83
+ };
84
+
85
+ // clang-format off
86
+ Lit.render(html`
87
+ <devtools-floating-button
88
+ icon-name=${icon}
89
+ title=${action.title()}
90
+ jslogcontext="ask-ai"
91
+ @click=${onClick}
92
+ @mousedown=${(ev: Event) => ev.stopPropagation()}>
93
+ </devtools-floating-button>
94
+ `, this.aiButtonContainer);
95
+ // clang-format on
96
+ }
97
+ }
59
98
  }
60
99
 
61
100
  export class ExpandableApplicationPanelTreeElement extends ApplicationPanelTreeElement {
@@ -317,7 +317,7 @@ export class CookieItemsView extends UI.Widget.VBox {
317
317
  }
318
318
 
319
319
  private updateAiAssistanceContext(cookie: SDK.Cookie.Cookie|null): void {
320
- if (!cookie || cookie.httpOnly()) {
320
+ if (cookie && cookie.httpOnly()) {
321
321
  UI.Context.Context.instance().setFlavor(AiAssistanceModel.StorageItem.StorageItem, null);
322
322
  return;
323
323
  }
@@ -332,7 +332,7 @@ export class CookieItemsView extends UI.Widget.VBox {
332
332
  return;
333
333
  }
334
334
 
335
- const storageItem = new AiAssistanceModel.StorageItem.CookieItem(mainPageOrigin, this.cookieDomain, cookie.name());
335
+ const storageItem = new AiAssistanceModel.StorageItem.CookieItem(mainPageOrigin, this.cookieDomain, cookie?.name());
336
336
  UI.Context.Context.instance().setFlavor(AiAssistanceModel.StorageItem.StorageItem, storageItem);
337
337
  }
338
338
 
@@ -64,3 +64,14 @@ devtools-icon.navigator-font-tree-item {
64
64
  .no-device-bound-session {
65
65
  font-style: italic;
66
66
  }
67
+
68
+ .ai-button-container {
69
+ display: none;
70
+ position: absolute;
71
+ z-index: 999;
72
+ right: var(--sys-size-3);
73
+ }
74
+
75
+ .tree-outline li:hover .ai-button-container {
76
+ display: inline-flex;
77
+ }
@@ -28,8 +28,8 @@ function renderHeader(content: Lit.LitTemplate|Node|UI.Widget.Widget, isCause: b
28
28
  }
29
29
 
30
30
  function formatName(frame: StackTrace.StackTrace.ParsedErrorStackFrame): string {
31
- let name = frame.name || '';
32
- const isInline = Boolean(frame.rawName) && frame.name !== frame.rawName;
31
+ const isInline = frame.isInline;
32
+ let name = isInline ? (frame.name || '') : (frame.rawName || frame.name || '');
33
33
  const shouldAppendMethodAlias = !isInline && frame.methodName && name && name !== frame.methodName &&
34
34
  !name.endsWith('.' + frame.methodName) && !name.endsWith(' ' + frame.methodName);
35
35
  if (shouldAppendMethodAlias) {
@@ -105,10 +105,6 @@ function renderFrameSuffix(frame: StackTrace.StackTrace.ParsedErrorStackFrame):
105
105
 
106
106
  const DEFAULT_VIEW = (input: ViewInput, _output: object, target: HTMLElement): void => {
107
107
  const renderError = (error: Bindings.SymbolizedError.SymbolizedError, isCause: boolean): Lit.LitTemplate => {
108
- if (error instanceof Bindings.SymbolizedError.SymbolizedSyntaxError) {
109
- console.error('SymbolizedErrorWidget received an unsupported error type:', error);
110
- return Lit.nothing;
111
- }
112
108
  if (error instanceof Bindings.SymbolizedError.UnparsableError) {
113
109
  const fragment = ConsoleViewMessage.linkifyWithCustomLinkifier(
114
110
  error.errorStack,
@@ -130,7 +126,14 @@ const DEFAULT_VIEW = (input: ViewInput, _output: object, target: HTMLElement): v
130
126
  maxLength: UI.UIUtils.MaxLengthForDisplayedURLsInConsole,
131
127
  ignoreListManager: input.ignoreListManager,
132
128
  };
133
- const headerContent = html`${error.message}`;
129
+
130
+ let headerContent = html`${error.message}`;
131
+ if (error.syntaxErrorLocation) {
132
+ const linkElement = Components.Linkifier.Linkifier.linkifyUILocation(error.syntaxErrorLocation, linkOptions);
133
+ linkElement.tabIndex = -1;
134
+ headerContent = html`${error.message} (at ${linkElement})`;
135
+ }
136
+
134
137
  const header = renderHeader(headerContent, isCause);
135
138
  const syncFrames = error.stackTrace.syncFragment.frames;
136
139
  // clang-format off
@@ -177,6 +177,7 @@ export class DevicesSettingsTab extends UI.Widget.VBox implements
177
177
  device.horizontal.height = 400;
178
178
  device.vertical.width = 400;
179
179
  device.vertical.height = 700;
180
+ device.userAgent = navigator.userAgent;
180
181
  this.#customDeviceList.addNewItem(this.emulatedDevicesList.custom().length, device);
181
182
  }
182
183
 
@@ -221,7 +221,7 @@ export class SourcesPanel extends UI.Panel.Panel implements
221
221
  #paused?: boolean;
222
222
  private switchToPausedTargetTimeout?: number;
223
223
  private executionLineLocation?: Bindings.DebuggerWorkspaceBinding.Location|null;
224
- private sidebarPaneStack?: UI.View.ViewLocation;
224
+ private sidebarPaneStack?: UI.ViewManager.StackLocation;
225
225
  private tabbedLocationHeader?: Element|null;
226
226
  private extensionSidebarPanesContainer?: UI.View.ViewLocation;
227
227
  sidebarPaneView?: UI.Widget.VBox|UI.SplitWidget.SplitWidget;
@@ -477,6 +477,7 @@ export class SourcesPanel extends UI.Panel.Panel implements
477
477
 
478
478
  toggleDebuggerSidebar(): void {
479
479
  this.splitWidget.toggleSidebar();
480
+ this.sidebarPaneStack?.notifyVisibilityChanged(this.splitWidget.sidebarIsShowing());
480
481
  }
481
482
 
482
483
  private debuggerPaused(event: Common.EventTarget.EventTargetEvent<SDK.DebuggerModel.DebuggerModel>): void {