chrome-devtools-frontend 1.0.1592129 → 1.0.1593518

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 (125) hide show
  1. package/front_end/Images/src/tab-move.svg +1 -0
  2. package/front_end/application_tokens.css +4 -4
  3. package/front_end/core/host/UserMetrics.ts +2 -1
  4. package/front_end/core/root/ExperimentNames.ts +1 -0
  5. package/front_end/entrypoints/main/MainImpl.ts +8 -0
  6. package/front_end/generated/InspectorBackendCommands.ts +3 -1
  7. package/front_end/generated/SupportedCSSProperties.js +2 -2
  8. package/front_end/generated/protocol-mapping.d.ts +13 -0
  9. package/front_end/generated/protocol-proxy-api.d.ts +12 -0
  10. package/front_end/generated/protocol.ts +75 -0
  11. package/front_end/models/ai_assistance/agents/AiAgent.ts +24 -1
  12. package/front_end/models/ai_assistance/agents/BreakpointDebuggerAgent.ts +320 -26
  13. package/front_end/models/ai_assistance/agents/BreakpointDebuggerAgentOverlay.ts +87 -0
  14. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +8 -8
  15. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +79 -48
  16. package/front_end/models/ai_assistance/agents/StylingAgent.ts +16 -2
  17. package/front_end/models/computed_style/ComputedStyleModel.ts +40 -6
  18. package/front_end/models/javascript_metadata/NativeFunctions.js +6 -6
  19. package/front_end/panels/accessibility/AXBreadcrumbsPane.ts +5 -3
  20. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +39 -7
  21. package/front_end/panels/ai_assistance/README.md +61 -0
  22. package/front_end/panels/ai_assistance/components/ChatMessage.ts +141 -27
  23. package/front_end/panels/ai_assistance/components/ChatView.ts +5 -1
  24. package/front_end/panels/ai_assistance/components/MarkdownRendererWithCodeBlock.ts +55 -1
  25. package/front_end/panels/ai_assistance/components/WalkthroughView.ts +19 -7
  26. package/front_end/panels/ai_assistance/components/chatMessage.css +30 -0
  27. package/front_end/panels/ai_assistance/components/walkthroughView.css +12 -7
  28. package/front_end/panels/animation/AnimationGroupPreviewUI.ts +1 -1
  29. package/front_end/panels/application/CookieItemsView.ts +194 -134
  30. package/front_end/panels/application/DeviceBoundSessionsTreeElement.ts +1 -1
  31. package/front_end/panels/application/ServiceWorkerUpdateCycleView.ts +1 -0
  32. package/front_end/panels/application/StorageItemsToolbar.ts +25 -2
  33. package/front_end/panels/application/components/BackForwardCacheView.ts +4 -2
  34. package/front_end/panels/application/cookieItemsView.css +28 -26
  35. package/front_end/panels/autofill/AutofillView.ts +1 -1
  36. package/front_end/panels/browser_debugger/DOMBreakpointsSidebarPane.ts +161 -154
  37. package/front_end/panels/browser_debugger/XHRBreakpointsSidebarPane.ts +1 -0
  38. package/front_end/panels/browser_debugger/domBreakpointsSidebarPane.css +58 -36
  39. package/front_end/panels/console/ConsoleViewMessage.ts +2 -1
  40. package/front_end/panels/console/consoleView.css +7 -2
  41. package/front_end/panels/elements/ComputedStyleWidget.ts +16 -26
  42. package/front_end/panels/elements/ElementsPanel.ts +26 -3
  43. package/front_end/panels/elements/ElementsTreeElement.ts +1 -0
  44. package/front_end/panels/elements/LayoutPane.ts +8 -7
  45. package/front_end/panels/elements/StandaloneStylesContainer.ts +254 -0
  46. package/front_end/panels/elements/StylePropertyTreeElement.ts +33 -0
  47. package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +148 -1
  48. package/front_end/panels/elements/components/ComputedStyleTrace.ts +4 -0
  49. package/front_end/panels/elements/components/ElementsBreadcrumbs.ts +1 -1
  50. package/front_end/panels/elements/components/StylePropertyEditor.ts +2 -1
  51. package/front_end/panels/elements/components/computedStyleProperty.css +1 -1
  52. package/front_end/panels/elements/elements-meta.ts +3 -5
  53. package/front_end/panels/elements/elements.ts +2 -0
  54. package/front_end/panels/elements/stylePropertiesTreeOutline.css +6 -0
  55. package/front_end/panels/lighthouse/LighthouseReportRenderer.ts +1 -1
  56. package/front_end/panels/linear_memory_inspector/components/LinearMemoryValueInterpreter.ts +1 -1
  57. package/front_end/panels/linear_memory_inspector/components/ValueInterpreterDisplay.ts +1 -1
  58. package/front_end/panels/media/PlayerListView.ts +1 -1
  59. package/front_end/panels/network/NetworkLogViewColumns.ts +2 -1
  60. package/front_end/panels/network/components/RequestHeaderSection.ts +1 -1
  61. package/front_end/panels/protocol_monitor/JSONEditor.ts +1 -1
  62. package/front_end/panels/recorder/components/RecordingListView.ts +1 -1
  63. package/front_end/panels/recorder/components/StepEditor.ts +3 -3
  64. package/front_end/panels/settings/KeybindsSettingsTab.ts +2 -1
  65. package/front_end/panels/sources/components/HeadersView.ts +2 -2
  66. package/front_end/panels/timeline/components/BreadcrumbsUI.ts +1 -1
  67. package/front_end/panels/timeline/components/SidebarAnnotationsTab.ts +1 -1
  68. package/front_end/panels/timeline/components/metricCard.css +0 -4
  69. package/front_end/third_party/chromium/README.chromium +1 -1
  70. package/front_end/third_party/puppeteer/README.chromium +2 -2
  71. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Navigation.d.ts.map +1 -1
  72. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Navigation.js +1 -0
  73. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Navigation.js.map +1 -1
  74. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.js +1 -1
  75. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.js.map +1 -1
  76. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +1 -1
  77. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
  78. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  79. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
  80. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.js +1 -0
  81. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.js.map +1 -1
  82. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
  83. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
  84. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
  85. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  86. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  87. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  88. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +6 -6
  89. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Navigation.d.ts.map +1 -1
  90. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Navigation.js +1 -0
  91. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Navigation.js.map +1 -1
  92. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.js +1 -1
  93. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.js.map +1 -1
  94. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +1 -1
  95. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
  96. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
  97. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.js +1 -0
  98. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.js.map +1 -1
  99. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
  100. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
  101. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
  102. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  103. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  104. package/front_end/third_party/puppeteer/package/package.json +4 -4
  105. package/front_end/third_party/puppeteer/package/src/bidi/core/Navigation.ts +1 -0
  106. package/front_end/third_party/puppeteer/package/src/cdp/BrowserContext.ts +1 -1
  107. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +1 -1
  108. package/front_end/third_party/puppeteer/package/src/node/ChromeLauncher.ts +1 -0
  109. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  110. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  111. package/front_end/ui/components/suggestion_input/SuggestionInput.ts +7 -12
  112. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +13 -2
  113. package/front_end/ui/components/tree_outline/TreeOutline.ts +6 -2
  114. package/front_end/ui/components/tree_outline/treeOutline.css +5 -0
  115. package/front_end/ui/legacy/ListControl.ts +5 -3
  116. package/front_end/ui/legacy/ListWidget.ts +1 -1
  117. package/front_end/ui/legacy/SoftContextMenu.ts +2 -1
  118. package/front_end/ui/legacy/Treeoutline.ts +1 -0
  119. package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +44 -24
  120. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +4 -2
  121. package/front_end/ui/legacy/components/quick_open/FilteredListWidget.ts +1 -1
  122. package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +31 -0
  123. package/front_end/ui/visual_logging/Debugging.ts +4 -0
  124. package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
  125. package/package.json +1 -1
@@ -2,14 +2,13 @@
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-imperative-dom-api */
6
-
7
5
  import * as Common from '../../core/common/common.js';
8
6
  import * as i18n from '../../core/i18n/i18n.js';
9
7
  import type * as Platform from '../../core/platform/platform.js';
10
8
  import * as SDK from '../../core/sdk/sdk.js';
11
9
  import * as Protocol from '../../generated/protocol.js';
12
10
  import * as UI from '../../ui/legacy/legacy.js';
11
+ import * as Lit from '../../ui/lit/lit.js';
13
12
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
14
13
  import * as PanelsCommon from '../common/common.js';
15
14
  import * as Sources from '../sources/sources.js';
@@ -107,38 +106,118 @@ const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined
107
106
  const DOM_BREAKPOINT_DOCUMENTATION_URL =
108
107
  'https://developer.chrome.com/docs/devtools/javascript/breakpoints#dom' as Platform.DevToolsPath.UrlString;
109
108
 
109
+ const {html, render, Directives} = Lit;
110
+
111
+ export interface Breakpoint {
112
+ breakpoint: SDK.DOMDebuggerModel.DOMBreakpoint;
113
+ label: string;
114
+ isHighlighted: boolean;
115
+ isFocused: boolean;
116
+ }
117
+
118
+ export interface ViewInput {
119
+ breakpoints: Breakpoint[];
120
+ onBreakpointClick: (breakpoint: SDK.DOMDebuggerModel.DOMBreakpoint) => void;
121
+ onBreakpointCheckboxClick: (breakpoint: SDK.DOMDebuggerModel.DOMBreakpoint) => void;
122
+ onBreakpointContextMenu: (breakpoint: SDK.DOMDebuggerModel.DOMBreakpoint, event: Event) => void;
123
+ onBreakpointKeyDown: (breakpoint: SDK.DOMDebuggerModel.DOMBreakpoint, event: Event) => void;
124
+ }
125
+
126
+ export type View = (input: ViewInput, output: undefined, target: HTMLElement) => void;
127
+
128
+ export const DEFAULT_VIEW: View = (input, _output, target) => {
129
+ const hasBreakpoints = input.breakpoints.length > 0;
130
+
131
+ // clang-format off
132
+ render(
133
+ html`
134
+ <style>${domBreakpointsSidebarPaneStyles}</style>
135
+ <div class="dom-breakpoints-container" jslog=${VisualLogging.section('sources.dom-breakpoints').track({ resize: true })}>
136
+ ${hasBreakpoints ? html
137
+ `<ul class="breakpoint-list"
138
+ aria-label=${i18nString(UIStrings.domBreakpointsList)}>
139
+ ${input.breakpoints.map(item => {
140
+ const {breakpoint} = item;
141
+ const checkedStateText = breakpoint.enabled ? i18nString(UIStrings.checked) : i18nString(UIStrings.unchecked);
142
+ const linkified = PanelsCommon.DOMLinkifier.Linkifier.instance().linkify(
143
+ breakpoint.node, {preventKeyboardFocus: true, tooltip: undefined});
144
+ return html`
145
+ <li class=${`breakpoint-entry ${item.isHighlighted ? 'breakpoint-hit' : ''}`}
146
+ tabindex=${item.isFocused ? '0' : '-1'}
147
+ @click=${() => input.onBreakpointClick(breakpoint)}
148
+ @contextmenu=${(e: Event) => input.onBreakpointContextMenu(breakpoint, e)}
149
+ @keydown=${(e: Event) => input.onBreakpointKeyDown(breakpoint, e)}
150
+ aria-label=${i18nString(UIStrings.sSS, { PH1: item.label, PH2: linkified.deepTextContent(), PH3: checkedStateText })}
151
+ aria-description=${item.isHighlighted ? i18nString(UIStrings.sBreakpointHit, { PH1: checkedStateText }) : checkedStateText}
152
+ jslog=${VisualLogging.domBreakpoint().context(breakpoint.type).track({ keydown: 'ArrowUp|ArrowDown|PageUp|PageDown' })}>
153
+ <devtools-checkbox
154
+ class="checkbox-label"
155
+ .checked=${breakpoint.enabled}
156
+ @click=${(e: Event) => e.stopPropagation()}
157
+ @change=${() => input.onBreakpointCheckboxClick(breakpoint)}
158
+ tabindex="-1"
159
+ aria-label=${i18nString(UIStrings.sS, { PH1: item.label, PH2: linkified.deepTextContent() })}
160
+ aria-description=${Directives.ifDefined(item.isHighlighted ? i18nString(UIStrings.breakpointHit) : undefined)}
161
+ jslog=${VisualLogging.toggle().track({ click: true })}>
162
+ </devtools-checkbox>
163
+ <div class="dom-breakpoint">
164
+ <code class="monospace" style="display: block;">${linkified}</code>
165
+ <div>${item.label}</div>
166
+ </div>
167
+ </li>`;
168
+ })}
169
+ </ul>` : html
170
+ `<div class="placeholder">
171
+ <div class="gray-info-message">${i18nString(UIStrings.noBreakpoints)}</div>
172
+ <devtools-widget .widgetConfig=${UI.Widget.widgetConfig(UI.EmptyWidget.EmptyWidget, {
173
+ header: i18nString(UIStrings.noBreakpoints),
174
+ text: i18nString(UIStrings.domBreakpointsDescription),
175
+ link: DOM_BREAKPOINT_DOCUMENTATION_URL,
176
+ })}></devtools-widget>
177
+ </div>`}
178
+ </div>
179
+ `,
180
+ target
181
+ );
182
+ // clang-format on
183
+ };
184
+
110
185
  let domBreakpointsSidebarPaneInstance: DOMBreakpointsSidebarPane;
111
186
 
112
187
  export class DOMBreakpointsSidebarPane extends UI.Widget.VBox implements
113
- UI.ContextFlavorListener.ContextFlavorListener, UI.ListControl.ListDelegate<SDK.DOMDebuggerModel.DOMBreakpoint> {
114
- elementToCheckboxes: WeakMap<Element, UI.UIUtils.CheckboxLabel>;
115
- readonly #emptyElement: HTMLElement;
116
- readonly #breakpoints: UI.ListModel.ListModel<SDK.DOMDebuggerModel.DOMBreakpoint>;
117
- #list: UI.ListControl.ListControl<SDK.DOMDebuggerModel.DOMBreakpoint>;
118
- #highlightedBreakpoint: SDK.DOMDebuggerModel.DOMBreakpoint|null;
119
-
120
- private constructor() {
188
+ UI.ContextFlavorListener.ContextFlavorListener {
189
+ readonly #breakpoints: SDK.DOMDebuggerModel.DOMBreakpoint[] = [];
190
+ #highlightedBreakpoint: SDK.DOMDebuggerModel.DOMBreakpoint|null = null;
191
+ #focusedBreakpoint: SDK.DOMDebuggerModel.DOMBreakpoint|null = null;
192
+ readonly #view: View;
193
+
194
+ set highlightedBreakpoint(breakpoint: SDK.DOMDebuggerModel.DOMBreakpoint|null) {
195
+ this.#highlightedBreakpoint = breakpoint;
196
+ this.requestUpdate();
197
+ }
198
+
199
+ set focusedBreakpoint(breakpoint: SDK.DOMDebuggerModel.DOMBreakpoint|null) {
200
+ if (this.#focusedBreakpoint === breakpoint) {
201
+ return;
202
+ }
203
+ this.#focusedBreakpoint = breakpoint;
204
+ this.#synchronizeFocusedBreakpoint();
205
+ this.requestUpdate();
206
+ }
207
+
208
+ #synchronizeFocusedBreakpoint(): void {
209
+ if (this.#focusedBreakpoint && !this.#breakpoints.includes(this.#focusedBreakpoint)) {
210
+ this.#focusedBreakpoint = null;
211
+ }
212
+ if (!this.#focusedBreakpoint && this.#breakpoints.length > 0) {
213
+ this.#focusedBreakpoint = this.#breakpoints[0];
214
+ }
215
+ }
216
+
217
+ constructor(view = DEFAULT_VIEW) {
121
218
  super({useShadowDom: true});
122
- this.registerRequiredCSS(domBreakpointsSidebarPaneStyles);
123
-
124
- this.elementToCheckboxes = new WeakMap();
125
-
126
- this.contentElement.setAttribute(
127
- 'jslog', `${VisualLogging.section('sources.dom-breakpoints').track({resize: true})}`);
128
- this.contentElement.classList.add('dom-breakpoints-container');
129
- this.#emptyElement = this.contentElement.createChild('div', 'placeholder');
130
- this.#emptyElement.createChild('div', 'gray-info-message').textContent = i18nString(UIStrings.noBreakpoints);
131
- const emptyWidget =
132
- new UI.EmptyWidget.EmptyWidget(UIStrings.noBreakpoints, i18nString(UIStrings.domBreakpointsDescription));
133
- emptyWidget.link = DOM_BREAKPOINT_DOCUMENTATION_URL;
134
- emptyWidget.show(this.#emptyElement);
135
-
136
- this.#breakpoints = new UI.ListModel.ListModel();
137
- this.#list = new UI.ListControl.ListControl(this.#breakpoints, this, UI.ListControl.ListMode.NonViewport);
138
- this.contentElement.appendChild(this.#list.element);
139
- this.#list.element.classList.add('breakpoint-list', 'hidden');
140
- UI.ARIAUtils.markAsList(this.#list.element);
141
- UI.ARIAUtils.setLabel(this.#list.element, i18nString(UIStrings.domBreakpointsList));
219
+
220
+ this.#view = view;
142
221
 
143
222
  SDK.TargetManager.TargetManager.instance().addModelListener(
144
223
  SDK.DOMDebuggerModel.DOMDebuggerModel, SDK.DOMDebuggerModel.Events.DOM_BREAKPOINT_ADDED, this.breakpointAdded,
@@ -158,7 +237,6 @@ export class DOMBreakpointsSidebarPane extends UI.Widget.VBox implements
158
237
  }
159
238
  }
160
239
 
161
- this.#highlightedBreakpoint = null;
162
240
  this.update();
163
241
  }
164
242
 
@@ -169,93 +247,41 @@ export class DOMBreakpointsSidebarPane extends UI.Widget.VBox implements
169
247
  return domBreakpointsSidebarPaneInstance;
170
248
  }
171
249
 
172
- createElementForItem(item: SDK.DOMDebuggerModel.DOMBreakpoint): Element {
173
- const element = document.createElement('div');
174
- element.classList.add('breakpoint-entry');
175
- element.setAttribute(
176
- 'jslog',
177
- `${VisualLogging.domBreakpoint().context(item.type).track({keydown: 'ArrowUp|ArrowDown|PageUp|PageDown'})}`);
178
- element.addEventListener('contextmenu', this.contextMenu.bind(this, item), true);
179
- UI.ARIAUtils.markAsListitem(element);
180
- element.tabIndex = -1;
181
-
182
- const checkbox = UI.UIUtils.CheckboxLabel.create(/* title */ undefined, item.enabled);
183
- checkbox.addEventListener('click', this.checkboxClicked.bind(this, item), false);
184
- checkbox.tabIndex = -1;
185
- this.elementToCheckboxes.set(element, checkbox);
186
- element.appendChild(checkbox);
187
- element.addEventListener('keydown', event => {
188
- if (event.key === ' ') {
189
- checkbox.click();
190
- event.consume(true);
191
- }
192
- });
193
-
194
- const labelElement = document.createElement('div');
195
- labelElement.classList.add('dom-breakpoint');
196
- element.appendChild(labelElement);
197
- const description = document.createElement('div');
198
- const breakpointTypeLabel = BreakpointTypeLabels.get(item.type);
199
- description.textContent = breakpointTypeLabel ? breakpointTypeLabel() : null;
200
- const breakpointTypeText = breakpointTypeLabel ? breakpointTypeLabel() : '';
201
- UI.ARIAUtils.setLabel(checkbox, breakpointTypeText);
202
- checkbox.setAttribute('jslog', `${VisualLogging.toggle().track({click: true})}`);
203
- const checkedStateText = item.enabled ? i18nString(UIStrings.checked) : i18nString(UIStrings.unchecked);
204
- const linkifiedNode = document.createElement('monospace');
205
- linkifiedNode.style.display = 'block';
206
- labelElement.appendChild(linkifiedNode);
207
- const linkified = PanelsCommon.DOMLinkifier.Linkifier.instance().linkify(
208
- item.node, {preventKeyboardFocus: true, tooltip: undefined});
209
- linkifiedNode.appendChild(linkified);
210
- // Give the checkbox an aria-label as it is required for all form element
211
- UI.ARIAUtils.setLabel(
212
- checkbox, i18nString(UIStrings.sS, {PH1: breakpointTypeText, PH2: linkified.deepTextContent()}));
213
- // The parent list element is the one that actually gets focused.
214
- // Assign it an aria-label with complete information for the screen reader to read out properly
215
- UI.ARIAUtils.setLabel(
216
- element,
217
- i18nString(UIStrings.sSS, {PH1: breakpointTypeText, PH2: linkified.deepTextContent(), PH3: checkedStateText}));
218
-
219
- labelElement.appendChild(description);
220
-
221
- if (item === this.#highlightedBreakpoint) {
222
- element.classList.add('breakpoint-hit');
223
- UI.ARIAUtils.setDescription(element, i18nString(UIStrings.sBreakpointHit, {PH1: checkedStateText}));
224
- UI.ARIAUtils.setDescription(checkbox, i18nString(UIStrings.breakpointHit));
225
- } else {
226
- UI.ARIAUtils.setDescription(element, checkedStateText);
227
- }
228
-
229
- this.#emptyElement.classList.add('hidden');
230
- this.#list.element.classList.remove('hidden');
231
-
232
- return element;
233
- }
234
-
235
- heightForItem(_item: SDK.DOMDebuggerModel.DOMBreakpoint): number {
236
- return 0;
237
- }
238
-
239
- isItemSelectable(_item: SDK.DOMDebuggerModel.DOMBreakpoint): boolean {
240
- return true;
250
+ override performUpdate(): void {
251
+ const input: ViewInput = {
252
+ breakpoints: this.#breakpoints.map(breakpoint => ({
253
+ breakpoint,
254
+ label: BreakpointTypeLabels.get(breakpoint.type)?.() ?? '',
255
+ isHighlighted: breakpoint === this.#highlightedBreakpoint,
256
+ isFocused: breakpoint === this.#focusedBreakpoint,
257
+ })),
258
+ onBreakpointClick: this.onBreakpointClick.bind(this),
259
+ onBreakpointCheckboxClick: this.onBreakpointCheckboxClick.bind(this),
260
+ onBreakpointContextMenu: this.onBreakpointContextMenu.bind(this),
261
+ onBreakpointKeyDown: this.onBreakpointKeyDown.bind(this),
262
+ };
263
+ this.#view(input, undefined, this.contentElement);
241
264
  }
242
265
 
243
- updateSelectedItemARIA(_fromElement: Element|null, _toElement: Element|null): boolean {
244
- return true;
266
+ private onBreakpointClick(breakpoint: SDK.DOMDebuggerModel.DOMBreakpoint): void {
267
+ this.focusedBreakpoint = breakpoint;
245
268
  }
246
269
 
247
- selectedItemChanged(
248
- _from: SDK.DOMDebuggerModel.DOMBreakpoint|null, _to: SDK.DOMDebuggerModel.DOMBreakpoint|null,
249
- fromElement: HTMLElement|null, toElement: HTMLElement|null): void {
250
- if (fromElement) {
251
- fromElement.tabIndex = -1;
252
- }
253
-
254
- if (toElement) {
255
- this.setDefaultFocusedElement(toElement);
256
- toElement.tabIndex = 0;
257
- if (this.hasFocus()) {
258
- toElement.focus();
270
+ private onBreakpointKeyDown(breakpoint: SDK.DOMDebuggerModel.DOMBreakpoint, event: Event): void {
271
+ const keyboardEvent = event as KeyboardEvent;
272
+ if (keyboardEvent.key === ' ') {
273
+ this.onBreakpointCheckboxClick(breakpoint);
274
+ keyboardEvent.consume(true);
275
+ } else if (keyboardEvent.key === 'ArrowUp' || keyboardEvent.key === 'ArrowDown') {
276
+ const index = this.#breakpoints.indexOf(breakpoint);
277
+ const newIndex = keyboardEvent.key === 'ArrowUp' ? index - 1 : index + 1;
278
+ if (newIndex >= 0 && newIndex < this.#breakpoints.length) {
279
+ this.focusedBreakpoint = this.#breakpoints[newIndex];
280
+ void this.updateComplete.then(() => {
281
+ const entry = this.contentElement.querySelectorAll('.breakpoint-entry')[newIndex] as HTMLElement;
282
+ entry.focus();
283
+ });
284
+ keyboardEvent.consume(true);
259
285
  }
260
286
  }
261
287
  }
@@ -264,43 +290,28 @@ export class DOMBreakpointsSidebarPane extends UI.Widget.VBox implements
264
290
  this.addBreakpoint(event.data);
265
291
  }
266
292
 
267
- private breakpointToggled(event: Common.EventTarget.EventTargetEvent<SDK.DOMDebuggerModel.DOMBreakpoint>): void {
268
- const hadFocus = this.hasFocus();
269
- const breakpoint = event.data;
270
- this.#list.refreshItem(breakpoint);
271
- if (hadFocus) {
272
- this.focus();
273
- }
293
+ private breakpointToggled(_event: Common.EventTarget.EventTargetEvent<SDK.DOMDebuggerModel.DOMBreakpoint>): void {
294
+ this.requestUpdate();
274
295
  }
275
296
 
276
297
  private breakpointsRemoved(event: Common.EventTarget.EventTargetEvent<SDK.DOMDebuggerModel.DOMBreakpoint[]>): void {
277
- const hadFocus = this.hasFocus();
278
298
  const breakpoints = event.data;
279
- let lastIndex = -1;
280
299
  for (const breakpoint of breakpoints) {
281
300
  const index = this.#breakpoints.indexOf(breakpoint);
282
301
  if (index >= 0) {
283
- this.#breakpoints.remove(index);
284
- lastIndex = index;
302
+ this.#breakpoints.splice(index, 1);
285
303
  }
286
304
  }
287
- if (this.#breakpoints.length === 0) {
288
- this.#emptyElement.classList.remove('hidden');
289
- this.setDefaultFocusedElement(this.#emptyElement);
290
- this.#list.element.classList.add('hidden');
291
- } else if (lastIndex >= 0) {
292
- const breakpointToSelect = this.#breakpoints.at(lastIndex);
293
- if (breakpointToSelect) {
294
- this.#list.selectItem(breakpointToSelect);
295
- }
296
- }
297
- if (hadFocus) {
298
- this.focus();
299
- }
305
+ this.#synchronizeFocusedBreakpoint();
306
+ this.requestUpdate();
300
307
  }
301
308
 
302
309
  private addBreakpoint(breakpoint: SDK.DOMDebuggerModel.DOMBreakpoint): void {
303
- this.#breakpoints.insertWithComparator(breakpoint, (breakpointA, breakpointB) => {
310
+ if (this.#breakpoints.includes(breakpoint)) {
311
+ return;
312
+ }
313
+ this.#breakpoints.push(breakpoint);
314
+ this.#breakpoints.sort((breakpointA, breakpointB) => {
304
315
  if (breakpointA.type > breakpointB.type) {
305
316
  return -1;
306
317
  }
@@ -309,12 +320,12 @@ export class DOMBreakpointsSidebarPane extends UI.Widget.VBox implements
309
320
  }
310
321
  return 0;
311
322
  });
312
- if (!this.#list.selectedItem() || !this.hasFocus()) {
313
- this.#list.selectItem(this.#breakpoints.at(0));
314
- }
323
+ this.#synchronizeFocusedBreakpoint();
324
+ this.requestUpdate();
315
325
  }
316
326
 
317
- private contextMenu(breakpoint: SDK.DOMDebuggerModel.DOMBreakpoint, event: Event): void {
327
+ private onBreakpointContextMenu(breakpoint: SDK.DOMDebuggerModel.DOMBreakpoint, event: Event): void {
328
+ this.focusedBreakpoint = breakpoint;
318
329
  const contextMenu = new UI.ContextMenu.ContextMenu(event);
319
330
  contextMenu.defaultSection().appendItem(
320
331
  i18nString(UIStrings.revealDomNodeInElementsPanel), () => Common.Revealer.reveal(breakpoint.node),
@@ -328,9 +339,9 @@ export class DOMBreakpointsSidebarPane extends UI.Widget.VBox implements
328
339
  void contextMenu.show();
329
340
  }
330
341
 
331
- private checkboxClicked(breakpoint: SDK.DOMDebuggerModel.DOMBreakpoint, event: Event): void {
332
- breakpoint.domDebuggerModel.toggleDOMBreakpoint(
333
- breakpoint, event.target ? (event.target as HTMLInputElement).checked : false);
342
+ private onBreakpointCheckboxClick(breakpoint: SDK.DOMDebuggerModel.DOMBreakpoint): void {
343
+ this.focusedBreakpoint = breakpoint;
344
+ breakpoint.domDebuggerModel.toggleDOMBreakpoint(breakpoint, !breakpoint.enabled);
334
345
  }
335
346
 
336
347
  flavorChanged(_object: Object|null): void {
@@ -339,11 +350,7 @@ export class DOMBreakpointsSidebarPane extends UI.Widget.VBox implements
339
350
 
340
351
  update(): void {
341
352
  const details = UI.Context.Context.instance().flavor(SDK.DebuggerModel.DebuggerPausedDetails);
342
- if (this.#highlightedBreakpoint) {
343
- const oldHighlightedBreakpoint = this.#highlightedBreakpoint;
344
- this.#highlightedBreakpoint = null;
345
- this.#list.refreshItem(oldHighlightedBreakpoint);
346
- }
353
+ this.highlightedBreakpoint = null;
347
354
  if (!details?.auxData || details.reason !== Protocol.Debugger.PausedEventReason.DOM) {
348
355
  return;
349
356
  }
@@ -361,13 +368,13 @@ export class DOMBreakpointsSidebarPane extends UI.Widget.VBox implements
361
368
 
362
369
  for (const breakpoint of this.#breakpoints) {
363
370
  if (breakpoint.node === data.node && breakpoint.type === data.type) {
364
- this.#highlightedBreakpoint = breakpoint;
371
+ this.highlightedBreakpoint = breakpoint;
372
+ this.focusedBreakpoint = breakpoint;
365
373
  }
366
374
  }
367
375
  if (this.#highlightedBreakpoint) {
368
- this.#list.refreshItem(this.#highlightedBreakpoint);
376
+ void UI.ViewManager.ViewManager.instance().showView('sources.dom-breakpoints');
369
377
  }
370
- void UI.ViewManager.ViewManager.instance().showView('sources.dom-breakpoints');
371
378
  }
372
379
  }
373
380
 
@@ -238,6 +238,7 @@ export class XHRBreakpointsSidebarPane extends UI.Widget.VBox implements UI.Cont
238
238
  listItemElement.setAttribute('jslog', `${VisualLogging.item().track({
239
239
  click: true,
240
240
  dblclick: true,
241
+ resize: true,
241
242
  keydown: 'ArrowUp|ArrowDown|PageUp|PageDown|Enter|Space',
242
243
  })}`);
243
244
  return listItemElement;
@@ -4,40 +4,60 @@
4
4
  * found in the LICENSE file.
5
5
  */
6
6
 
7
- .dom-breakpoints-container {
8
- overflow: auto;
9
- }
7
+ @scope to (devtools-widget > *) {
8
+ :scope {
9
+ overflow: auto;
10
+ }
10
11
 
11
- .breakpoint-list {
12
- padding-bottom: 3px;
13
- }
12
+ .monospace {
13
+ font-family: var(--monospace-font-family);
14
+ font-size: var(--monospace-font-size);
15
+ }
14
16
 
15
- .breakpoint-list .dom-breakpoint > div {
16
- overflow: hidden;
17
- text-overflow: ellipsis;
18
- }
17
+ .dom-breakpoints-container {
18
+ flex-grow: 1;
19
+ }
19
20
 
20
- .breakpoint-entry {
21
- display: flex;
22
- white-space: nowrap;
23
- text-overflow: ellipsis;
24
- overflow: hidden;
25
- padding: 2px 0;
26
- }
21
+ .breakpoint-list {
22
+ padding: 0 0 3px;
23
+ list-style-type: none;
24
+ margin: 0;
25
+ }
27
26
 
28
- .breakpoint-entry:focus-visible {
29
- background-color: var(--sys-color-tonal-container);
30
- }
27
+ .breakpoint-list .dom-breakpoint > div {
28
+ overflow: hidden;
29
+ text-overflow: ellipsis;
30
+ }
31
31
 
32
- .breakpoint-hit {
33
- background-color: var(--sys-color-neutral-container);
34
- color: var(--sys-color-on-surface);
35
- }
32
+ .breakpoint-entry {
33
+ display: flex;
34
+ white-space: nowrap;
35
+ text-overflow: ellipsis;
36
+ overflow: hidden;
37
+ padding: 2px 0;
38
+ }
39
+
40
+ .breakpoint-entry:focus-visible {
41
+ background-color: var(--sys-color-tonal-container);
42
+ }
43
+
44
+ .breakpoint-hit {
45
+ background-color: var(--sys-color-neutral-container);
46
+ color: var(--sys-color-on-surface);
47
+ }
48
+
49
+ .placeholder {
50
+ display: flex;
51
+ height: 100%;
52
+ justify-content: center;
53
+ }
36
54
 
37
- .placeholder {
38
- display: flex;
39
- height: 100%;
40
- justify-content: center;
55
+ .gray-info-message {
56
+ display: flex;
57
+ justify-content: center;
58
+ align-items: center;
59
+ padding: 20px;
60
+ }
41
61
  }
42
62
 
43
63
  :host-context(.sources.panel) .empty-view-scroller {
@@ -49,14 +69,16 @@
49
69
  }
50
70
 
51
71
  @media (forced-colors: active) {
52
- .breakpoint-entry:focus-visible,
53
- .breakpoint-list .breakpoint-entry:hover {
54
- forced-color-adjust: none;
55
- background-color: Highlight;
56
- }
72
+ @scope to (devtools-widget > *) {
73
+ .breakpoint-entry:focus-visible,
74
+ .breakpoint-list .breakpoint-entry:hover {
75
+ forced-color-adjust: none;
76
+ background-color: Highlight;
77
+ }
57
78
 
58
- .breakpoint-entry:focus-visible *,
59
- .breakpoint-list .breakpoint-entry:hover * {
60
- color: HighlightText;
79
+ .breakpoint-entry:focus-visible *,
80
+ .breakpoint-list .breakpoint-entry:hover * {
81
+ color: HighlightText;
82
+ }
61
83
  }
62
84
  }
@@ -1449,6 +1449,7 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
1449
1449
  this.elementInternal.className = 'console-message-wrapper';
1450
1450
  this.elementInternal.setAttribute('jslog', `${VisualLogging.item('console-message').track({
1451
1451
  click: true,
1452
+ resize: true,
1452
1453
  keydown: 'ArrowUp|ArrowDown|ArrowLeft|ArrowRight|Enter|Space|Home|End',
1453
1454
  })}`);
1454
1455
  this.elementInternal.removeChildren();
@@ -1675,7 +1676,7 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
1675
1676
  Breakpoints.BreakpointManager.EMPTY_BREAKPOINT_CONDITION, /* enabled */ true,
1676
1677
  /* isLogpoint */ false, Breakpoints.BreakpointManager.BreakpointOrigin.OTHER);
1677
1678
  const aiPanel = await AiAssistancePanel.AiAssistancePanel.instance();
1678
- void aiPanel.handleBreakpointConversation(uiLocation);
1679
+ void aiPanel.handleBreakpointConversation(uiLocation, this.text);
1679
1680
  }
1680
1681
  };
1681
1682
 
@@ -435,11 +435,16 @@
435
435
  --display-ignored-formatted-stack-frame: var(--display-formatted-stack-frame-default);
436
436
  }
437
437
 
438
- &:has(.formatted-stack-frame .ignore-list-link):has(.formatted-stack-frame .devtools-link:not(.ignore-list-link)) {
438
+ &:has(.formatted-stack-frame .ignore-list-link):has(.formatted-stack-frame .devtools-link:not(.ignore-list-link)),
439
+ &:has(.formatted-stack-frame .ignore-list-link):has(.stack-preview-container.has-non-ignored-links) {
439
440
  /* If there are ignored frames and unignored frames, then we want
440
441
  to enable the show more/less links. To do that we override some
441
442
  variables to always display the structured stack trace, but possibly
442
- only the links at the bottom of it, as we share its show more/less links. */
443
+ only the links at the bottom of it, as we share its show more/less links.
444
+ We also check the structured stack trace (StackTracePreviewContent) for
445
+ non-ignored links, so that when all inline Error frames are ignored but
446
+ the console.error() call stack has non-ignored frames (e.g. in async
447
+ traces), the toggle is still shown. See crbug.com/379788109. */
443
448
  --override-display-stack-preview-toggle-link: table-row;
444
449
  --override-display-stack-preview-hidden-div: block;
445
450
 
@@ -297,6 +297,7 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
297
297
  #computedStyleModel?: ComputedStyleModule.ComputedStyleModel.ComputedStyleModel;
298
298
  #nodeStyle: ComputedStyleModule.ComputedStyleModel.ComputedStyle|null = null;
299
299
  #matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles|null = null;
300
+ #propertyTraces: Map<string, SDK.CSSProperty.CSSProperty[]>|null = null;
300
301
  private readonly showInheritedComputedStylePropertiesSetting: Common.Settings.Setting<boolean>;
301
302
  private readonly groupComputedStylesSetting: Common.Settings.Setting<boolean>;
302
303
  private filterRegex: RegExp|null = null;
@@ -335,9 +336,9 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
335
336
  #filterIsRegex = false;
336
337
  #allowUserControl = true;
337
338
 
338
- constructor() {
339
- super({useShadowDom: true});
340
- this.#view = DEFAULT_VIEW;
339
+ constructor(element?: HTMLElement, view = DEFAULT_VIEW) {
340
+ super(element, {useShadowDom: true});
341
+ this.#view = view;
341
342
 
342
343
  this.contentElement.classList.add('styles-sidebar-computed-style-widget');
343
344
 
@@ -368,7 +369,10 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
368
369
  this.#computedStylesTree.classList.toggle('computed-narrow', isNarrow);
369
370
  }
370
371
 
371
- get filterText(): string {
372
+ get filterText(): RegExp|string {
373
+ if (this.#filterIsRegex) {
374
+ return new RegExp(this.#filterText);
375
+ }
372
376
  return this.#filterText;
373
377
  }
374
378
 
@@ -384,6 +388,7 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
384
388
  this.#filterText = newFilter.source;
385
389
  this.#filterIsRegex = true;
386
390
  }
391
+ this.filterRegex = this.#buildFilterRegex(this.#filterText);
387
392
  this.requestUpdate();
388
393
  }
389
394
 
@@ -432,6 +437,11 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
432
437
  this.requestUpdate();
433
438
  }
434
439
 
440
+ set propertyTraces(propertyTraces: Map<string, SDK.CSSProperty.CSSProperty[]>|null) {
441
+ this.#propertyTraces = propertyTraces;
442
+ this.requestUpdate();
443
+ }
444
+
435
445
  get computedStyleModel(): ComputedStyleModule.ComputedStyleModel.ComputedStyleModel|undefined {
436
446
  return this.#computedStyleModel;
437
447
  }
@@ -477,7 +487,7 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
477
487
  uniqueProperties.sort(propertySorter);
478
488
 
479
489
  const node = nodeStyle.node;
480
- const propertyTraces = this.computePropertyTraces(matchedStyles);
490
+ const propertyTraces = this.#propertyTraces || new Map();
481
491
  const nonInheritedProperties = this.computeNonInheritedProperties(matchedStyles);
482
492
  const showInherited = this.#shouldShowAllStyles();
483
493
  const tree: Array<TreeOutline.TreeOutlineUtils.TreeNode<ComputedStyleData>> = [];
@@ -518,7 +528,7 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
518
528
  }
519
529
 
520
530
  const node = nodeStyle.node;
521
- const propertyTraces = this.computePropertyTraces(matchedStyles);
531
+ const propertyTraces = this.#propertyTraces || new Map();
522
532
  const nonInheritedProperties = this.computeNonInheritedProperties(matchedStyles);
523
533
  const showInherited = this.showInheritedComputedStylePropertiesSetting.get();
524
534
 
@@ -664,26 +674,6 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
664
674
  void contextMenu.show();
665
675
  }
666
676
 
667
- private computePropertyTraces(matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles):
668
- Map<string, SDK.CSSProperty.CSSProperty[]> {
669
- const result = new Map<string, SDK.CSSProperty.CSSProperty[]>();
670
- for (const style of matchedStyles.nodeStyles()) {
671
- const allProperties = style.allProperties();
672
- for (const property of allProperties) {
673
- if (!property.activeInStyle() || !matchedStyles.propertyState(property)) {
674
- continue;
675
- }
676
- if (!result.has(property.name)) {
677
- result.set(property.name, []);
678
- }
679
- // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
680
- // @ts-expect-error
681
- result.get(property.name).push(property);
682
- }
683
- }
684
- return result;
685
- }
686
-
687
677
  private computeNonInheritedProperties(matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles): Set<string> {
688
678
  const result = new Set<string>();
689
679
  for (const style of matchedStyles.nodeStyles()) {