chrome-devtools-frontend 1.0.1581449 → 1.0.1582745
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.
- package/agents/prompts/merging-devtools-module.md +144 -0
- package/agents/prompts/ui-widgets.md +351 -0
- package/agents/prompts/verification.md +2 -1
- package/docs/contributing/README.md +5 -6
- package/docs/contributing/changes.md +1 -2
- package/docs/styleguide/ux/README.md +1 -1
- package/front_end/core/sdk/OverlayModel.ts +4 -2
- package/front_end/core/sdk/RemoteObject.ts +7 -1
- package/front_end/core/sdk/StorageKeyManager.ts +6 -1
- package/front_end/core/sdk/Target.ts +4 -2
- package/front_end/entrypoint_template.html +5 -1
- package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +31 -40
- package/front_end/entrypoints/greendev_floaty/floaty.css +41 -1
- package/front_end/entrypoints/greendev_floaty/floaty.html +8 -1
- package/front_end/entrypoints/greendev_floaty/greendev_floaty.ts +5 -5
- package/front_end/entrypoints/node_app/app/NodeMain.ts +19 -1
- package/front_end/entrypoints/node_app/node_app.ts +34 -0
- package/front_end/generated/InspectorBackendCommands.ts +1 -1
- package/front_end/generated/SupportedCSSProperties.js +2 -0
- package/front_end/generated/protocol.ts +0 -6
- package/front_end/models/ai_assistance/AiConversation.ts +10 -0
- package/front_end/models/ai_assistance/agents/AiAgent.ts +2 -0
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +26 -4
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +85 -7
- package/front_end/models/ai_assistance/agents/NetworkAgent.ts +2 -6
- package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +66 -2
- package/front_end/models/computed_style/ComputedStyleModel.ts +26 -0
- package/front_end/models/greendev/Prototypes.ts +1 -10
- package/front_end/models/issues_manager/ConnectionAllowlistIssue.ts +75 -0
- package/front_end/models/issues_manager/CookieIssue.ts +0 -28
- package/front_end/models/issues_manager/FederatedAuthRequestIssue.ts +0 -30
- package/front_end/models/issues_manager/IssuesManager.ts +5 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistInvalidAllowlistItemType.md +12 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistInvalidHeader.md +12 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistInvalidUrlPattern.md +8 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistItemNotInnerList.md +12 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistMoreThanOneList.md +7 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistReportingEndpointNotToken.md +10 -0
- package/front_end/models/issues_manager/issues_manager.ts +2 -0
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +93 -6
- package/front_end/panels/ai_assistance/components/ChatInput.ts +8 -4
- package/front_end/panels/application/ApplicationPanelSidebar.ts +13 -11
- package/front_end/panels/application/DOMStorageModel.ts +1 -1
- package/front_end/panels/application/ResourcesPanel.ts +10 -5
- package/front_end/panels/application/preloading/PreloadingView.ts +8 -1
- package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +4 -1
- package/front_end/panels/application/preloading/components/PreloadingGrid.ts +2 -1
- package/front_end/panels/application/preloading/components/PreloadingString.ts +12 -3
- package/front_end/panels/application/preloading/helper/PreloadingForward.ts +14 -0
- package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +37 -3
- package/front_end/panels/changes/ChangesSidebar.ts +2 -6
- package/front_end/panels/common/AiCodeCompletionTeaser.ts +13 -3
- package/front_end/panels/common/aiCodeCompletionTeaser.css +6 -0
- package/front_end/panels/console/ConsoleSidebar.ts +3 -11
- package/front_end/panels/console_counters/WarningErrorCounter.ts +16 -10
- package/front_end/panels/elements/ComputedStyleWidget.ts +55 -37
- package/front_end/panels/elements/PlatformFontsWidget.ts +23 -10
- package/front_end/panels/greendev/GreenDevPanel.css +42 -1
- package/front_end/panels/greendev/GreenDevPanel.ts +30 -1
- package/front_end/panels/lighthouse/LighthouseStartView.ts +3 -5
- package/front_end/panels/lighthouse/lighthouseStartView.css +6 -0
- package/front_end/panels/network/NetworkLogView.ts +6 -6
- package/front_end/panels/network/RequestInitiatorView.ts +27 -19
- package/front_end/panels/network/RequestTimingView.ts +1 -1
- package/front_end/panels/settings/AISettingsTab.ts +1 -5
- package/front_end/panels/settings/KeybindsSettingsTab.ts +4 -3
- package/front_end/panels/settings/SettingsScreen.ts +0 -51
- package/front_end/panels/sources/OutlineQuickOpen.ts +19 -0
- package/front_end/panels/timeline/AnimationsTrackAppender.ts +4 -1
- package/front_end/panels/timeline/InteractionsTrackAppender.ts +1 -1
- package/front_end/panels/timeline/TimelinePanel.ts +25 -0
- package/front_end/panels/timeline/TimelineUIUtils.ts +13 -16
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/lighthouse/README.chromium +2 -2
- package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +145 -144
- package/front_end/third_party/lighthouse/report/bundle.js +12 -5
- package/front_end/third_party/lighthouse/report-assets/report-generator.mjs +2 -2
- package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +5 -1
- package/front_end/ui/legacy/ListControl.ts +28 -1
- package/front_end/ui/legacy/Toolbar.ts +4 -4
- package/front_end/ui/legacy/Treeoutline.ts +5 -5
- package/front_end/ui/legacy/UIUtils.ts +26 -10
- package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +10 -13
- package/front_end/ui/legacy/components/utils/Linkifier.ts +4 -7
- package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
- package/inspector_overlay/main.ts +18 -3
- package/inspector_overlay/tool_green_dev_anchors.css +54 -0
- package/inspector_overlay/tool_green_dev_anchors.ts +164 -0
- package/inspector_overlay/tool_persistent.ts +14 -0
- package/package.json +1 -1
- package/docs/contributing/design.md +0 -166
- package/docs/design_guidelines.md +0 -1
- package/front_end/models/issues_manager/descriptions/federatedAuthRequestClientMetadataHttpNotFound.md +0 -1
- package/front_end/models/issues_manager/descriptions/federatedAuthRequestClientMetadataInvalidResponse.md +0 -1
- package/front_end/models/issues_manager/descriptions/federatedAuthRequestClientMetadataNoResponse.md +0 -1
|
@@ -12,9 +12,11 @@ import * as IssuesManager from '../../models/issues_manager/issues_manager.js';
|
|
|
12
12
|
import type * as IconButton from '../../ui/components/icon_button/icon_button.js';
|
|
13
13
|
import * as IssueCounter from '../../ui/components/issue_counter/issue_counter.js';
|
|
14
14
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
15
|
-
import
|
|
15
|
+
import * as Lit from '../../ui/lit/lit.js';
|
|
16
16
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
17
17
|
|
|
18
|
+
const {html, nothing, render} = Lit;
|
|
19
|
+
|
|
18
20
|
const UIStrings = {
|
|
19
21
|
/**
|
|
20
22
|
* @description The console error count in the Warning Error Counter shown in the main toolbar (top-left in DevTools). The error count refers to the number of errors currently present in the JavaScript console.
|
|
@@ -95,21 +97,25 @@ const DEFAULT_VIEW: View = (input, _output, target) => {
|
|
|
95
97
|
|
|
96
98
|
render(
|
|
97
99
|
html`<div class="status-buttons"
|
|
98
|
-
|
|
100
|
+
>${
|
|
101
|
+
errors + warnings ? html`<icon-button
|
|
99
102
|
.data=${iconData}
|
|
100
103
|
title=${consoleTitle}
|
|
101
|
-
class=${'small'
|
|
104
|
+
class=${'small'}
|
|
102
105
|
jslog=${VisualLogging.counter('console').track({
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
></icon-button
|
|
106
|
-
|
|
106
|
+
click: true
|
|
107
|
+
})}
|
|
108
|
+
></icon-button>` :
|
|
109
|
+
nothing}${
|
|
110
|
+
issues ? html`<devtools-issue-counter
|
|
111
|
+
class=${'main-toolbar'}
|
|
107
112
|
title=${issuesTitle}
|
|
108
113
|
.data=${issueCounterData}
|
|
109
114
|
jslog=${VisualLogging.counter('issue').track({
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
></devtools-issue-counter
|
|
115
|
+
click: true
|
|
116
|
+
})}
|
|
117
|
+
></devtools-issue-counter>` :
|
|
118
|
+
nothing}</div>`,
|
|
113
119
|
target);
|
|
114
120
|
};
|
|
115
121
|
|
|
@@ -53,7 +53,7 @@ import {categorizePropertyName, type Category, DefaultCategoryOrder} from './Pro
|
|
|
53
53
|
import {Renderer, rendererBase, type RenderingContext, StringRenderer, URLRenderer} from './PropertyRenderer.js';
|
|
54
54
|
import {StylePropertiesSection} from './StylePropertiesSection.js';
|
|
55
55
|
|
|
56
|
-
const {html} = Lit;
|
|
56
|
+
const {html, render} = Lit;
|
|
57
57
|
|
|
58
58
|
const UIStrings = {
|
|
59
59
|
/**
|
|
@@ -197,7 +197,7 @@ const createTraceElement =
|
|
|
197
197
|
return trace;
|
|
198
198
|
};
|
|
199
199
|
|
|
200
|
-
|
|
200
|
+
// clang-format off
|
|
201
201
|
class ColorRenderer extends rendererBase(SDK.CSSPropertyParserMatchers.ColorMatch) {
|
|
202
202
|
// clang-format on
|
|
203
203
|
override render(match: SDK.CSSPropertyParserMatchers.ColorMatch, context: RenderingContext): Node[] {
|
|
@@ -261,21 +261,47 @@ type ComputedStyleData = {
|
|
|
261
261
|
name: string,
|
|
262
262
|
};
|
|
263
263
|
|
|
264
|
+
interface ComputedStyleWidgetInput {
|
|
265
|
+
computedStylesTree: TreeOutline.TreeOutline.TreeOutline<ComputedStyleData>;
|
|
266
|
+
toolbar: HTMLElement;
|
|
267
|
+
hasMatches: boolean;
|
|
268
|
+
computedStyleModel: ComputedStyleModule.ComputedStyleModel.ComputedStyleModel;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
type View = (input: ComputedStyleWidgetInput, output: null, target: HTMLElement) => void;
|
|
272
|
+
|
|
273
|
+
export const DEFAULT_VIEW: View = (input, _output, target) => {
|
|
274
|
+
// clang-format off
|
|
275
|
+
render(html`
|
|
276
|
+
<div class="styles-sidebar-pane-toolbar">${input.toolbar}</div>
|
|
277
|
+
<div class="computed-style-tree-outline-container">
|
|
278
|
+
${input.computedStylesTree}
|
|
279
|
+
</div>
|
|
280
|
+
${!input.hasMatches ? html`<div class="gray-info-message">${i18nString(UIStrings.noMatchingProperty)}</div>` : ''}
|
|
281
|
+
<div class="platform-fonts-widget-container">
|
|
282
|
+
<devtools-widget .widgetConfig=${UI.Widget.widgetConfig(PlatformFontsWidget, { sharedModel: input.computedStyleModel})}></devtools-widget>
|
|
283
|
+
</div>
|
|
284
|
+
`, target);
|
|
285
|
+
// clang-format on
|
|
286
|
+
};
|
|
287
|
+
|
|
264
288
|
export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
265
289
|
private computedStyleModel: ComputedStyleModule.ComputedStyleModel.ComputedStyleModel;
|
|
266
290
|
private readonly showInheritedComputedStylePropertiesSetting: Common.Settings.Setting<boolean>;
|
|
267
291
|
private readonly groupComputedStylesSetting: Common.Settings.Setting<boolean>;
|
|
268
292
|
input: UI.Toolbar.ToolbarInput;
|
|
269
293
|
private filterRegex: RegExp|null;
|
|
270
|
-
private readonly noMatchesElement: HTMLElement;
|
|
271
294
|
private readonly linkifier: Components.Linkifier.Linkifier;
|
|
272
295
|
private readonly imagePreviewPopover: ImagePreviewPopover;
|
|
273
296
|
|
|
274
297
|
#computedStylesTree = new TreeOutline.TreeOutline.TreeOutline<ComputedStyleData>();
|
|
275
298
|
#treeData?: TreeOutline.TreeOutline.TreeOutlineData<ComputedStyleData>;
|
|
299
|
+
readonly #view: View;
|
|
300
|
+
private readonly toolbarElement: HTMLElement;
|
|
276
301
|
|
|
277
302
|
constructor(computedStyleModel: ComputedStyleModule.ComputedStyleModel.ComputedStyleModel) {
|
|
278
303
|
super({useShadowDom: true});
|
|
304
|
+
this.#view = DEFAULT_VIEW;
|
|
279
305
|
this.registerRequiredCSS(computedStyleSidebarPaneStyles);
|
|
280
306
|
|
|
281
307
|
this.contentElement.classList.add('styles-sidebar-computed-style-widget');
|
|
@@ -295,8 +321,12 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
295
321
|
this.requestUpdate();
|
|
296
322
|
});
|
|
297
323
|
|
|
298
|
-
|
|
299
|
-
|
|
324
|
+
this.toolbarElement = document.createElement('div');
|
|
325
|
+
this.toolbarElement.classList.add('hbox', 'styles-sidebar-pane-toolbar');
|
|
326
|
+
const toolbar = document.createElement('devtools-toolbar');
|
|
327
|
+
toolbar.classList.add('styles-pane-toolbar');
|
|
328
|
+
this.toolbarElement.appendChild(toolbar);
|
|
329
|
+
|
|
300
330
|
const filterInput = new UI.Toolbar.ToolbarFilter(undefined, 1, 1, undefined, undefined, false);
|
|
301
331
|
filterInput.addEventListener(UI.Toolbar.ToolbarInput.Event.TEXT_CHANGED, this.onFilterChanged, this);
|
|
302
332
|
toolbar.appendToolbarItem(filterInput);
|
|
@@ -308,11 +338,6 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
308
338
|
toolbar.appendToolbarItem(
|
|
309
339
|
new UI.Toolbar.ToolbarSettingCheckbox(this.groupComputedStylesSetting, undefined, i18nString(UIStrings.group)));
|
|
310
340
|
|
|
311
|
-
this.noMatchesElement = this.contentElement.createChild('div', 'gray-info-message');
|
|
312
|
-
this.noMatchesElement.textContent = i18nString(UIStrings.noMatchingProperty);
|
|
313
|
-
|
|
314
|
-
this.contentElement.appendChild(this.#computedStylesTree);
|
|
315
|
-
|
|
316
341
|
this.linkifier = new Components.Linkifier.Linkifier(maxLinkLength);
|
|
317
342
|
|
|
318
343
|
this.imagePreviewPopover = new ImagePreviewPopover(this.contentElement, event => {
|
|
@@ -323,8 +348,7 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
323
348
|
return null;
|
|
324
349
|
}, () => this.computedStyleModel.node);
|
|
325
350
|
|
|
326
|
-
|
|
327
|
-
fontsWidget.show(this.contentElement);
|
|
351
|
+
this.#updateView({hasMatches: true});
|
|
328
352
|
}
|
|
329
353
|
|
|
330
354
|
override onResize(): void {
|
|
@@ -342,11 +366,24 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
342
366
|
UI.Context.Context.instance().setFlavor(ComputedStyleWidget, null);
|
|
343
367
|
}
|
|
344
368
|
|
|
369
|
+
/**
|
|
370
|
+
* @param input.hasMatches Whether any properties matched the current filter (or if any properties exist at all).
|
|
371
|
+
*/
|
|
372
|
+
#updateView({hasMatches}: {hasMatches: boolean}): void {
|
|
373
|
+
this.#view(
|
|
374
|
+
{
|
|
375
|
+
computedStylesTree: this.#computedStylesTree,
|
|
376
|
+
toolbar: this.toolbarElement,
|
|
377
|
+
hasMatches,
|
|
378
|
+
computedStyleModel: this.computedStyleModel,
|
|
379
|
+
},
|
|
380
|
+
null, this.contentElement);
|
|
381
|
+
}
|
|
382
|
+
|
|
345
383
|
override async performUpdate(): Promise<void> {
|
|
346
|
-
const
|
|
347
|
-
await Promise.all([this.computedStyleModel.fetchComputedStyle(), this.fetchMatchedCascade()]);
|
|
384
|
+
const {computedStyle: nodeStyles, matchedStyles} = await this.computedStyleModel.fetchAllComputedStyleInfo();
|
|
348
385
|
if (!nodeStyles || !matchedStyles) {
|
|
349
|
-
this
|
|
386
|
+
this.#updateView({hasMatches: false});
|
|
350
387
|
return;
|
|
351
388
|
}
|
|
352
389
|
const shouldGroupComputedStyles = this.groupComputedStylesSetting.get();
|
|
@@ -357,25 +394,6 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
357
394
|
}
|
|
358
395
|
}
|
|
359
396
|
|
|
360
|
-
private async fetchMatchedCascade(): Promise<SDK.CSSMatchedStyles.CSSMatchedStyles|null> {
|
|
361
|
-
const node = this.computedStyleModel.node;
|
|
362
|
-
if (!node || !this.computedStyleModel.cssModel()) {
|
|
363
|
-
return null;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
const cssModel = this.computedStyleModel.cssModel();
|
|
367
|
-
if (!cssModel) {
|
|
368
|
-
return null;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
return await cssModel.cachedMatchedCascadeForNode(node).then(validateStyles.bind(this));
|
|
372
|
-
|
|
373
|
-
function validateStyles(this: ComputedStyleWidget, matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles|null):
|
|
374
|
-
SDK.CSSMatchedStyles.CSSMatchedStyles|null {
|
|
375
|
-
return matchedStyles && matchedStyles.node() === this.computedStyleModel.node ? matchedStyles : null;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
397
|
private async rebuildAlphabeticalList(
|
|
380
398
|
nodeStyle: ComputedStyleModule.ComputedStyleModel.ComputedStyle,
|
|
381
399
|
matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles): Promise<void> {
|
|
@@ -426,7 +444,7 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
426
444
|
this.linkifier.reset();
|
|
427
445
|
const cssModel = this.computedStyleModel.cssModel();
|
|
428
446
|
if (!nodeStyle || !matchedStyles || !cssModel) {
|
|
429
|
-
this
|
|
447
|
+
this.#updateView({hasMatches: false});
|
|
430
448
|
return;
|
|
431
449
|
}
|
|
432
450
|
|
|
@@ -648,7 +666,7 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
648
666
|
defaultRenderer: this.#treeData.defaultRenderer,
|
|
649
667
|
compact: this.#treeData.compact,
|
|
650
668
|
};
|
|
651
|
-
this
|
|
669
|
+
this.#updateView({hasMatches: Boolean(tree.length)});
|
|
652
670
|
}
|
|
653
671
|
|
|
654
672
|
private async filterGroupLists(): Promise<void> {
|
|
@@ -675,7 +693,7 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
675
693
|
compact: this.#treeData.compact,
|
|
676
694
|
};
|
|
677
695
|
await this.#computedStylesTree.expandRecursively(0);
|
|
678
|
-
this
|
|
696
|
+
this.#updateView({hasMatches: Boolean(tree.length)});
|
|
679
697
|
}
|
|
680
698
|
}
|
|
681
699
|
|
|
@@ -78,24 +78,37 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
|
|
|
78
78
|
};
|
|
79
79
|
|
|
80
80
|
export class PlatformFontsWidget extends UI.Widget.VBox {
|
|
81
|
-
private readonly sharedModel: ComputedStyle.ComputedStyleModel.ComputedStyleModel;
|
|
82
81
|
readonly #view: View;
|
|
82
|
+
#sharedModel: ComputedStyle.ComputedStyleModel.ComputedStyleModel|null = null;
|
|
83
83
|
|
|
84
|
-
constructor(
|
|
85
|
-
super({useShadowDom: true});
|
|
84
|
+
constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
|
|
85
|
+
super(element, {useShadowDom: true});
|
|
86
86
|
this.#view = view;
|
|
87
87
|
this.registerRequiredCSS(platformFontsWidgetStyles);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
get sharedModel(): ComputedStyle.ComputedStyleModel.ComputedStyleModel|null {
|
|
91
|
+
return this.#sharedModel;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
set sharedModel(model: ComputedStyle.ComputedStyleModel.ComputedStyleModel) {
|
|
95
|
+
if (model !== this.sharedModel) {
|
|
96
|
+
this.sharedModel?.removeEventListener(
|
|
97
|
+
ComputedStyle.ComputedStyleModel.Events.CSS_MODEL_CHANGED, this.requestUpdate, this);
|
|
98
|
+
this.sharedModel?.removeEventListener(
|
|
99
|
+
ComputedStyle.ComputedStyleModel.Events.COMPUTED_STYLE_CHANGED, this.requestUpdate, this);
|
|
100
|
+
|
|
101
|
+
model.addEventListener(ComputedStyle.ComputedStyleModel.Events.CSS_MODEL_CHANGED, this.requestUpdate, this);
|
|
102
|
+
model.addEventListener(ComputedStyle.ComputedStyleModel.Events.COMPUTED_STYLE_CHANGED, this.requestUpdate, this);
|
|
103
|
+
}
|
|
88
104
|
|
|
89
|
-
this
|
|
90
|
-
this.
|
|
91
|
-
ComputedStyle.ComputedStyleModel.Events.CSS_MODEL_CHANGED, this.requestUpdate, this);
|
|
92
|
-
this.sharedModel.addEventListener(
|
|
93
|
-
ComputedStyle.ComputedStyleModel.Events.COMPUTED_STYLE_CHANGED, this.requestUpdate, this);
|
|
105
|
+
this.#sharedModel = model;
|
|
106
|
+
void this.requestUpdate();
|
|
94
107
|
}
|
|
95
108
|
|
|
96
109
|
override async performUpdate(): Promise<void> {
|
|
97
|
-
const cssModel = this
|
|
98
|
-
const node = this
|
|
110
|
+
const cssModel = this.#sharedModel?.cssModel();
|
|
111
|
+
const node = this.#sharedModel?.node;
|
|
99
112
|
if (!node || !cssModel) {
|
|
100
113
|
this.#view({platformFonts: null}, {}, this.contentElement);
|
|
101
114
|
return;
|
|
@@ -234,8 +234,49 @@
|
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
.green-dev-floaty-disclaimer {
|
|
237
|
-
font-size:
|
|
237
|
+
font-size: 15px;
|
|
238
238
|
color: #666;
|
|
239
239
|
text-align: center;
|
|
240
240
|
margin-top: 8px;
|
|
241
|
+
position: relative; /* For tooltip positioning */
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.disclaimer-link {
|
|
245
|
+
color: #666; /* Match text color */
|
|
246
|
+
text-decoration: underline;
|
|
247
|
+
cursor: pointer;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.disclaimer-tooltip {
|
|
251
|
+
display: none;
|
|
252
|
+
position: absolute;
|
|
253
|
+
bottom: 100%; /* Position above */
|
|
254
|
+
left: 50%;
|
|
255
|
+
transform: translateX(-50%);
|
|
256
|
+
width: 300px;
|
|
257
|
+
padding: 12px;
|
|
258
|
+
background-color: #fff;
|
|
259
|
+
border: 1px solid #ccc;
|
|
260
|
+
border-radius: 8px;
|
|
261
|
+
box-shadow: 0 2px 10px rgb(0 0 0 / 20%);
|
|
262
|
+
z-index: 1000;
|
|
263
|
+
text-align: left;
|
|
264
|
+
font-size: 16px;
|
|
265
|
+
line-height: 1.4;
|
|
266
|
+
color: #333;
|
|
267
|
+
white-space: normal; /* Ensure text wraps */
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.disclaimer-link:hover + .disclaimer-tooltip,
|
|
271
|
+
.disclaimer-tooltip:hover {
|
|
272
|
+
display: block;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.learn-more-link {
|
|
276
|
+
color: #0b57d0;
|
|
277
|
+
text-decoration: none;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.learn-more-link:hover {
|
|
281
|
+
text-decoration: underline;
|
|
241
282
|
}
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
/* eslint-disable @devtools/no-imperative-dom-api */
|
|
5
5
|
|
|
6
6
|
import type * as Common from '../../core/common/common.js';
|
|
7
|
+
import * as Host from '../../core/host/host.js';
|
|
8
|
+
import type * as Platform from '../../core/platform/platform.js';
|
|
7
9
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
8
10
|
import type * as Protocol from '../../generated/protocol.js';
|
|
9
11
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
@@ -186,7 +188,34 @@ export class GreenDevPanel extends UI.Panel.Panel {
|
|
|
186
188
|
|
|
187
189
|
const disclaimer = document.createElement('div');
|
|
188
190
|
disclaimer.className = 'green-dev-floaty-disclaimer';
|
|
189
|
-
|
|
191
|
+
|
|
192
|
+
const link = document.createElement('span');
|
|
193
|
+
link.className = 'disclaimer-link';
|
|
194
|
+
link.textContent = 'Relevant data';
|
|
195
|
+
disclaimer.appendChild(link);
|
|
196
|
+
|
|
197
|
+
disclaimer.appendChild(document.createTextNode(' is sent to Google'));
|
|
198
|
+
|
|
199
|
+
const tooltip = document.createElement('div');
|
|
200
|
+
tooltip.className = 'disclaimer-tooltip';
|
|
201
|
+
|
|
202
|
+
tooltip.appendChild(document.createTextNode(
|
|
203
|
+
'Chat messages and any data the inspected page can access via Web APIs are sent to Google and may be seen by human reviewers to improve this feature. This is an experimental AI feature and won\'t always get it right.'));
|
|
204
|
+
tooltip.appendChild(document.createElement('br'));
|
|
205
|
+
tooltip.appendChild(document.createElement('br'));
|
|
206
|
+
|
|
207
|
+
const learnMore = document.createElement('a');
|
|
208
|
+
const href = 'https://developer.chrome.com/docs/devtools/ai-assistance' as Platform.DevToolsPath.UrlString;
|
|
209
|
+
learnMore.href = href;
|
|
210
|
+
learnMore.className = 'learn-more-link';
|
|
211
|
+
learnMore.textContent = 'Learn about AI in DevTools';
|
|
212
|
+
learnMore.addEventListener('click', event => {
|
|
213
|
+
event.preventDefault();
|
|
214
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance.openInNewTab(href);
|
|
215
|
+
});
|
|
216
|
+
tooltip.appendChild(learnMore);
|
|
217
|
+
|
|
218
|
+
disclaimer.appendChild(tooltip);
|
|
190
219
|
blueCard.appendChild(disclaimer);
|
|
191
220
|
|
|
192
221
|
content.appendChild(blueCard);
|
|
@@ -166,8 +166,6 @@ export class StartView extends UI.Widget.Widget {
|
|
|
166
166
|
checkbox.setIndeterminate(true);
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
|
-
UI.ARIAUtils.markAsGroup(categoryFormElements);
|
|
170
|
-
UI.ARIAUtils.setLabel(categoryFormElements, i18nString(UIStrings.categories));
|
|
171
169
|
}
|
|
172
170
|
|
|
173
171
|
private render(): void {
|
|
@@ -194,10 +192,10 @@ export class StartView extends UI.Widget.Widget {
|
|
|
194
192
|
<div class="lighthouse-form-elements" $="device-type-form-elements"></div>
|
|
195
193
|
</div>
|
|
196
194
|
<div class="lighthouse-form-categories">
|
|
197
|
-
<
|
|
198
|
-
<
|
|
195
|
+
<fieldset class="lighthouse-form-section lighthouse-form-categories-fieldset">
|
|
196
|
+
<legend class="lighthouse-form-section-label">${i18nString(UIStrings.categories)}</legend>
|
|
199
197
|
<div class="lighthouse-form-elements" $="categories-form-elements"></div>
|
|
200
|
-
</
|
|
198
|
+
</fieldset>
|
|
201
199
|
</div>
|
|
202
200
|
</div>
|
|
203
201
|
<div $="warning-text" class="lighthouse-warning-text hidden"></div>
|
|
@@ -1933,14 +1933,14 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
1933
1933
|
const isThrottling = existingConditions &&
|
|
1934
1934
|
existingConditions.conditions !== SDK.NetworkManager.BlockingConditions &&
|
|
1935
1935
|
existingConditions.conditions !== SDK.NetworkManager.NoThrottlingConditions;
|
|
1936
|
+
const croppedURL = Platform.StringUtilities.trimMiddle(urlPattern.constructorString, maxBlockedURLLength);
|
|
1936
1937
|
blockingMenu.debugSection().appendItem(
|
|
1937
|
-
isBlocking ? i18nString(UIStrings.unblockS, {PH1:
|
|
1938
|
-
i18nString(UIStrings.blockRequestUrl),
|
|
1938
|
+
isBlocking ? i18nString(UIStrings.unblockS, {PH1: croppedURL}) : i18nString(UIStrings.blockRequestUrl),
|
|
1939
1939
|
() => isBlocking ? removeRequestCondition(urlPattern) :
|
|
1940
1940
|
addRequestCondition(urlPattern, SDK.NetworkManager.BlockingConditions),
|
|
1941
1941
|
{jslogContext: 'block-request-url'});
|
|
1942
1942
|
throttlingMenu.debugSection().appendItem(
|
|
1943
|
-
isThrottling ? i18nString(UIStrings.unthrottleS, {PH1:
|
|
1943
|
+
isThrottling ? i18nString(UIStrings.unthrottleS, {PH1: croppedURL}) :
|
|
1944
1944
|
i18nString(UIStrings.throttleRequestUrl),
|
|
1945
1945
|
() => isThrottling ? removeRequestCondition(urlPattern) :
|
|
1946
1946
|
addRequestCondition(urlPattern, SDK.NetworkManager.Slow3GConditions),
|
|
@@ -1959,14 +1959,14 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
1959
1959
|
const isThrottling = existingConditions &&
|
|
1960
1960
|
existingConditions.conditions !== SDK.NetworkManager.BlockingConditions &&
|
|
1961
1961
|
existingConditions.conditions !== SDK.NetworkManager.NoThrottlingConditions;
|
|
1962
|
+
const croppedURL = Platform.StringUtilities.trimMiddle(domainPattern.constructorString, maxBlockedURLLength);
|
|
1962
1963
|
blockingMenu.debugSection().appendItem(
|
|
1963
|
-
isBlocking ? i18nString(UIStrings.unblockS, {PH1:
|
|
1964
|
-
i18nString(UIStrings.blockRequestDomain),
|
|
1964
|
+
isBlocking ? i18nString(UIStrings.unblockS, {PH1: croppedURL}) : i18nString(UIStrings.blockRequestDomain),
|
|
1965
1965
|
() => isBlocking ? removeRequestCondition(domainPattern) :
|
|
1966
1966
|
addRequestCondition(domainPattern, SDK.NetworkManager.BlockingConditions),
|
|
1967
1967
|
{jslogContext: 'block-request-domain'});
|
|
1968
1968
|
throttlingMenu.debugSection().appendItem(
|
|
1969
|
-
isThrottling ? i18nString(UIStrings.unthrottleS, {PH1:
|
|
1969
|
+
isThrottling ? i18nString(UIStrings.unthrottleS, {PH1: croppedURL}) :
|
|
1970
1970
|
i18nString(UIStrings.throttleRequestDomain),
|
|
1971
1971
|
() => isThrottling ? removeRequestCondition(domainPattern) :
|
|
1972
1972
|
addRequestCondition(domainPattern, SDK.NetworkManager.Slow3GConditions),
|
|
@@ -37,7 +37,7 @@ const str_ = i18n.i18n.registerUIStrings('panels/network/RequestInitiatorView.ts
|
|
|
37
37
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
38
38
|
export interface ViewInput {
|
|
39
39
|
initiatorGraph: Logs.NetworkLog.InitiatorGraph;
|
|
40
|
-
|
|
40
|
+
stackTrace: StackTrace.StackTrace.StackTrace|null;
|
|
41
41
|
request: SDK.NetworkRequest.NetworkRequest;
|
|
42
42
|
linkifier: Components.Linkifier.Linkifier;
|
|
43
43
|
target?: SDK.Target.Target;
|
|
@@ -45,7 +45,7 @@ export interface ViewInput {
|
|
|
45
45
|
|
|
46
46
|
export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLElement): void => {
|
|
47
47
|
const hasInitiatorData =
|
|
48
|
-
input.initiatorGraph.initiators.size > 1 || input.initiatorGraph.initiated.size > 1 || input.
|
|
48
|
+
input.initiatorGraph.initiators.size > 1 || input.initiatorGraph.initiated.size > 1 || input.stackTrace;
|
|
49
49
|
|
|
50
50
|
if (!hasInitiatorData) {
|
|
51
51
|
render(
|
|
@@ -59,6 +59,9 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
const renderStackTraceSection = (): Lit.TemplateResult => {
|
|
62
|
+
if (!input.stackTrace) {
|
|
63
|
+
return html`${nothing}`;
|
|
64
|
+
}
|
|
62
65
|
return html`
|
|
63
66
|
<li role="treeitem" class="request-initiator-view-section-title" aria-expanded="true">
|
|
64
67
|
${i18nString(UIStrings.requestCallStack)}
|
|
@@ -67,7 +70,8 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
|
|
|
67
70
|
<devtools-widget .widgetConfig=${widgetConfig(Components.JSPresentationUtils.StackTracePreviewContent, {
|
|
68
71
|
target: input.target,
|
|
69
72
|
linkifier: input.linkifier,
|
|
70
|
-
options: {
|
|
73
|
+
options: {tabStops: true},
|
|
74
|
+
stackTrace: input.stackTrace,
|
|
71
75
|
})}></devtools-widget>
|
|
72
76
|
</li>
|
|
73
77
|
</ul>
|
|
@@ -146,7 +150,7 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
|
|
|
146
150
|
${requestInitiatorViewTreeStyles}
|
|
147
151
|
</style>
|
|
148
152
|
<ul role="tree">
|
|
149
|
-
${
|
|
153
|
+
${renderStackTraceSection()}
|
|
150
154
|
${
|
|
151
155
|
(input.initiatorGraph.initiators.size > 1 || input.initiatorGraph.initiated.size > 1) ?
|
|
152
156
|
renderInitiatorChain(input.initiatorGraph) :
|
|
@@ -184,32 +188,36 @@ export class RequestInitiatorView extends UI.Widget.VBox {
|
|
|
184
188
|
if (!initiator?.stack) {
|
|
185
189
|
return null;
|
|
186
190
|
}
|
|
191
|
+
const targetManager = SDK.TargetManager.TargetManager.instance();
|
|
187
192
|
const networkManager = SDK.NetworkManager.NetworkManager.forRequest(request);
|
|
188
|
-
const target = networkManager
|
|
193
|
+
const target = networkManager?.target() ?? targetManager.primaryPageTarget() ?? targetManager.rootTarget();
|
|
194
|
+
let stackTrace: StackTrace.StackTrace.StackTrace|null = null;
|
|
195
|
+
const preview = new Components.JSPresentationUtils.StackTracePreviewContent(
|
|
196
|
+
undefined, target ?? undefined, linkifier, {tabStops: focusableLink});
|
|
189
197
|
if (target) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
const preview = new Components.JSPresentationUtils.StackTracePreviewContent(
|
|
193
|
-
undefined, target, linkifier, {tabStops: focusableLink});
|
|
198
|
+
stackTrace = await Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance()
|
|
199
|
+
.createStackTraceFromProtocolRuntime(initiator.stack, target);
|
|
194
200
|
preview.stackTrace = stackTrace;
|
|
195
|
-
return {preview, stackTrace};
|
|
196
201
|
}
|
|
197
|
-
return {
|
|
198
|
-
preview: new Components.JSPresentationUtils.StackTracePreviewContent(
|
|
199
|
-
undefined, target, linkifier, {runtimeStackTrace: initiator.stack, tabStops: focusableLink}),
|
|
200
|
-
stackTrace: null
|
|
201
|
-
};
|
|
202
|
+
return {preview, stackTrace};
|
|
202
203
|
}
|
|
203
204
|
|
|
204
|
-
override performUpdate(): void {
|
|
205
|
+
override async performUpdate(): Promise<void> {
|
|
205
206
|
const initiatorGraph = Logs.NetworkLog.NetworkLog.instance().initiatorGraphForRequest(this.request);
|
|
206
|
-
const
|
|
207
|
+
const targetManager = SDK.TargetManager.TargetManager.instance();
|
|
207
208
|
const networkManager = SDK.NetworkManager.NetworkManager.forRequest(this.request);
|
|
208
|
-
const target = networkManager
|
|
209
|
+
const target = networkManager?.target() ?? targetManager.primaryPageTarget() ?? targetManager.rootTarget();
|
|
210
|
+
|
|
211
|
+
const rawStack = this.request.initiator()?.stack;
|
|
212
|
+
let stackTrace: StackTrace.StackTrace.StackTrace|null = null;
|
|
213
|
+
if (rawStack && target) {
|
|
214
|
+
stackTrace = await Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance()
|
|
215
|
+
.createStackTraceFromProtocolRuntime(rawStack, target);
|
|
216
|
+
}
|
|
209
217
|
|
|
210
218
|
const viewInput: ViewInput = {
|
|
211
219
|
initiatorGraph,
|
|
212
|
-
|
|
220
|
+
stackTrace,
|
|
213
221
|
request: this.request,
|
|
214
222
|
linkifier: this.linkifier,
|
|
215
223
|
target: target || undefined,
|
|
@@ -576,7 +576,7 @@ export class RequestTimingView extends UI.Widget.VBox {
|
|
|
576
576
|
calculator: this.#calculator,
|
|
577
577
|
requestStartTime: this.#request.startTime,
|
|
578
578
|
requestIssueTime: this.#request.issueTime(),
|
|
579
|
-
requestUnfinished:
|
|
579
|
+
requestUnfinished: !this.#request.finished,
|
|
580
580
|
fetchDetails: this.#fetchDetailsTree(),
|
|
581
581
|
routerDetails: this.#routerDetailsTree(),
|
|
582
582
|
wasThrottled: conditions?.urlPattern ? conditions : undefined,
|
|
@@ -10,7 +10,6 @@ import * as i18n from '../../core/i18n/i18n.js';
|
|
|
10
10
|
import type * as Platform from '../../core/platform/platform.js';
|
|
11
11
|
import * as Root from '../../core/root/root.js';
|
|
12
12
|
import * as AiAssistanceModel from '../../models/ai_assistance/ai_assistance.js';
|
|
13
|
-
import * as AiCodeGeneration from '../../models/ai_code_generation/ai_code_generation.js';
|
|
14
13
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
15
14
|
import * as Input from '../../ui/components/input/input.js';
|
|
16
15
|
import * as Switch from '../../ui/components/switch/switch.js';
|
|
@@ -537,10 +536,7 @@ export class AISettingsTab extends UI.Widget.VBox {
|
|
|
537
536
|
}
|
|
538
537
|
|
|
539
538
|
if (this.#aiCodeCompletionSetting) {
|
|
540
|
-
const
|
|
541
|
-
const isAiCodeGenerationEnabled =
|
|
542
|
-
AiCodeGeneration.AiCodeGeneration.AiCodeGeneration.isAiCodeGenerationEnabled(devtoolsLocale.locale);
|
|
543
|
-
const settingItems = isAiCodeGenerationEnabled ?
|
|
539
|
+
const settingItems = Root.Runtime.hostConfig.devToolsAiCodeGeneration?.enabled ?
|
|
544
540
|
[
|
|
545
541
|
{iconName: 'code', text: i18nString(UIStrings.asYouTypeRelevantDataIsBeingSentToGoogle)}, {
|
|
546
542
|
iconName: 'text-analysis',
|
|
@@ -222,8 +222,9 @@ export class KeybindsSettingsTab extends UI.Widget.VBox implements UI.ListContro
|
|
|
222
222
|
return 0;
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
isItemSelectable(
|
|
226
|
-
|
|
225
|
+
isItemSelectable(item: KeybindsItem): boolean {
|
|
226
|
+
// Category headers (UI.ActionRegistration.ActionCategory) should not be selectable
|
|
227
|
+
return item instanceof UI.ActionRegistration.Action;
|
|
227
228
|
}
|
|
228
229
|
|
|
229
230
|
selectedItemChanged(
|
|
@@ -314,7 +315,7 @@ export class KeybindsSettingsTab extends UI.Widget.VBox implements UI.ListContro
|
|
|
314
315
|
}
|
|
315
316
|
this.list.refreshAllItems();
|
|
316
317
|
if (!this.list.selectedItem()) {
|
|
317
|
-
this.list.
|
|
318
|
+
this.list.selectFirstItem();
|
|
318
319
|
}
|
|
319
320
|
}
|
|
320
321
|
|