chrome-devtools-frontend 1.0.1666631 → 1.0.1667564
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/front_end/core/host/AidaClient.ts +6 -4
- package/front_end/core/host/InspectorFrontendHostAPI.ts +1 -0
- package/front_end/core/host/InspectorFrontendHostStub.ts +3 -3
- package/front_end/core/host/UserMetrics.ts +49 -1
- package/front_end/core/sdk/CSSMatchedStyles.ts +2 -5
- package/front_end/core/sdk/CSSPropertyParserMatchers.ts +12 -0
- package/front_end/core/sdk/Connections.ts +1 -1
- package/front_end/core/sdk/DOMModel.test.api.ts +104 -0
- package/front_end/core/sdk/DOMModel.ts +23 -11
- package/front_end/core/sdk/DebuggerModel.ts +9 -9
- package/front_end/core/sdk/IsolateManager.ts +1 -1
- package/front_end/core/sdk/NetworkManager.ts +105 -4
- package/front_end/core/sdk/OverlayModel.ts +15 -14
- package/front_end/core/sdk/RemoteObject.ts +1 -1
- package/front_end/devtools_compatibility.js +1 -0
- package/front_end/entrypoints/main/MainImpl.ts +5 -2
- package/front_end/entrypoints/main/SimpleApp.ts +9 -3
- package/front_end/foundation/Universe.ts +6 -0
- package/front_end/models/ai_assistance/contexts/PerformanceTraceContext.ts +23 -10
- package/front_end/models/computed_style/ComputedStyleModel.ts +4 -7
- package/front_end/models/crux-manager/CrUXManager.ts +4 -0
- package/front_end/models/extensions/ExtensionAPI.ts +3 -3
- package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +2 -2
- package/front_end/models/live-metrics/LiveMetrics.ts +59 -19
- package/front_end/models/live-metrics/web-vitals-injected/README.md +1 -1
- package/front_end/models/live-metrics/web-vitals-injected/spec/spec.ts +6 -1
- package/front_end/models/live-metrics/web-vitals-injected/web-vitals-injected.ts +11 -3
- package/front_end/models/logs/LogManager.ts +1 -1
- package/front_end/models/persistence/FileSystemWorkspaceBinding.ts +1 -1
- package/front_end/models/source_map_scopes/FunctionCodeResolver.ts +6 -7
- package/front_end/models/workspace_diff/WorkspaceDiff.ts +13 -14
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +15 -7
- package/front_end/panels/application/BackgroundServiceView.ts +18 -20
- package/front_end/panels/autofill/AutofillView.ts +17 -17
- package/front_end/panels/autofill/autofillView.css +7 -8
- package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +31 -31
- package/front_end/panels/browser_debugger/DOMBreakpointsSidebarPane.ts +15 -15
- package/front_end/panels/browser_debugger/XHRBreakpointsSidebarPane.ts +12 -12
- package/front_end/panels/browser_debugger/browser_debugger-meta.ts +27 -27
- package/front_end/panels/common/AiCodeCompletionDisclaimer.ts +14 -6
- package/front_end/panels/common/AiCodeCompletionSummaryToolbar.ts +14 -6
- package/front_end/panels/common/AiCodeCompletionTeaser.ts +13 -6
- package/front_end/panels/common/GeminiRebrandPromoDialog.ts +1 -1
- package/front_end/panels/console/ConsoleInsightTeaser.ts +13 -6
- package/front_end/panels/console/ConsoleView.ts +6 -6
- package/front_end/panels/console_counters/WarningErrorCounter.ts +4 -4
- package/front_end/panels/coverage/CoverageModel.ts +11 -1
- package/front_end/panels/elements/StylePropertiesSection.ts +50 -17
- package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +18 -7
- package/front_end/panels/emulation/AdvancedApp.ts +18 -8
- package/front_end/panels/event_listeners/EventListenersView.ts +8 -8
- package/front_end/panels/explain/components/ConsoleInsight.ts +15 -7
- package/front_end/panels/network/NetworkLogView.ts +13 -14
- package/front_end/panels/screencast/ScreencastApp.ts +12 -6
- package/front_end/panels/screencast/ScreencastView.ts +37 -11
- package/front_end/panels/sensors/locationsSettingsTab.css +4 -0
- package/front_end/panels/settings/AISettingsTab.ts +13 -6
- package/front_end/panels/sources/DebuggerPlugin.ts +13 -2
- package/front_end/panels/timeline/components/LiveMetricsView.ts +14 -1
- package/front_end/panels/timeline/components/cpuThrottlingSelector.css +4 -0
- package/front_end/panels/timeline/components/liveMetricsView.css +28 -0
- package/front_end/panels/timeline/timeline-meta.ts +13 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/components/menus/menu.css +4 -0
- package/front_end/ui/components/menus/menuItem.css +4 -0
- package/front_end/ui/components/menus/selectMenu.css +4 -0
- package/front_end/ui/components/menus/selectMenuButton.css +4 -0
- package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +21 -10
- package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +22 -10
- package/front_end/ui/components/text_editor/config.ts +7 -0
- package/front_end/ui/legacy/AppProvider.ts +2 -1
- package/front_end/ui/legacy/RootView.ts +8 -1
- package/front_end/ui/legacy/UniverseRequestEvent.ts +19 -0
- package/front_end/ui/legacy/Widget.ts +49 -6
- package/front_end/ui/legacy/inspectorCommon.css +1 -1
- package/front_end/ui/legacy/legacy.ts +2 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import '../../ui/components/spinners/spinners.js';
|
|
6
6
|
import '../../ui/components/tooltips/tooltips.js';
|
|
7
7
|
|
|
8
|
+
import type * as Common from '../../core/common/common.js';
|
|
8
9
|
import * as Host from '../../core/host/host.js';
|
|
9
10
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
10
11
|
import * as Root from '../../core/root/root.js';
|
|
@@ -196,7 +197,8 @@ export class AiCodeCompletionDisclaimer extends UI.Widget.Widget {
|
|
|
196
197
|
#panel?: AiCodeCompletion.AiCodeCompletion.ContextFlavor;
|
|
197
198
|
|
|
198
199
|
#aidaAvailability?: Host.AidaClient.AidaAccessPreconditions;
|
|
199
|
-
#boundOnAidaAvailabilityChange:
|
|
200
|
+
#boundOnAidaAvailabilityChange:
|
|
201
|
+
(ev: Common.EventTarget.EventTargetEvent<Host.AidaClient.AidaAccessPreconditions>) => void;
|
|
200
202
|
|
|
201
203
|
constructor(element?: HTMLElement, view: View = DEFAULT_SUMMARY_TOOLBAR_VIEW) {
|
|
202
204
|
super(element);
|
|
@@ -249,14 +251,17 @@ export class AiCodeCompletionDisclaimer extends UI.Widget.Widget {
|
|
|
249
251
|
this.requestUpdate();
|
|
250
252
|
}
|
|
251
253
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
this.#aidaAvailability = currentAidaAvailability;
|
|
254
|
+
#updateAidaAvailability(aidaAvailability: Host.AidaClient.AidaAccessPreconditions): void {
|
|
255
|
+
if (aidaAvailability !== this.#aidaAvailability) {
|
|
256
|
+
this.#aidaAvailability = aidaAvailability;
|
|
256
257
|
this.requestUpdate();
|
|
257
258
|
}
|
|
258
259
|
}
|
|
259
260
|
|
|
261
|
+
#onAidaAvailabilityChange(ev: Common.EventTarget.EventTargetEvent<Host.AidaClient.AidaAccessPreconditions>): void {
|
|
262
|
+
this.#updateAidaAvailability(ev.data);
|
|
263
|
+
}
|
|
264
|
+
|
|
260
265
|
#onManageInSettingsTooltipClick(): void {
|
|
261
266
|
this.#viewOutput.hideTooltip?.();
|
|
262
267
|
void UI.ViewManager.ViewManager.instance().showView('chrome-ai');
|
|
@@ -279,7 +284,10 @@ export class AiCodeCompletionDisclaimer extends UI.Widget.Widget {
|
|
|
279
284
|
super.wasShown();
|
|
280
285
|
Host.AidaClient.HostConfigTracker.instance().addEventListener(
|
|
281
286
|
Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#boundOnAidaAvailabilityChange);
|
|
282
|
-
|
|
287
|
+
const initialAvailability = Host.AidaClient.HostConfigTracker.instance().aidaAvailability;
|
|
288
|
+
if (initialAvailability !== undefined) {
|
|
289
|
+
this.#updateAidaAvailability(initialAvailability);
|
|
290
|
+
}
|
|
283
291
|
}
|
|
284
292
|
|
|
285
293
|
override willHide(): void {
|
|
@@ -6,6 +6,7 @@ import '../../ui/components/spinners/spinners.js';
|
|
|
6
6
|
import '../../ui/components/tooltips/tooltips.js';
|
|
7
7
|
import '../../ui/kit/kit.js';
|
|
8
8
|
|
|
9
|
+
import type * as Common from '../../core/common/common.js';
|
|
9
10
|
import * as Host from '../../core/host/host.js';
|
|
10
11
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
11
12
|
import type * as AiCodeCompletion from '../../models/ai_code_completion/ai_code_completion.js';
|
|
@@ -116,7 +117,8 @@ export class AiCodeCompletionSummaryToolbar extends UI.Widget.Widget {
|
|
|
116
117
|
#panel: AiCodeCompletion.AiCodeCompletion.ContextFlavor;
|
|
117
118
|
|
|
118
119
|
#aidaAvailability?: Host.AidaClient.AidaAccessPreconditions;
|
|
119
|
-
#boundOnAidaAvailabilityChange:
|
|
120
|
+
#boundOnAidaAvailabilityChange:
|
|
121
|
+
(ev: Common.EventTarget.EventTargetEvent<Host.AidaClient.AidaAccessPreconditions>) => void;
|
|
120
122
|
|
|
121
123
|
constructor(props: AiCodeCompletionSummaryToolbarProps, view?: View) {
|
|
122
124
|
super();
|
|
@@ -130,14 +132,17 @@ export class AiCodeCompletionSummaryToolbar extends UI.Widget.Widget {
|
|
|
130
132
|
this.requestUpdate();
|
|
131
133
|
}
|
|
132
134
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
this.#aidaAvailability = currentAidaAvailability;
|
|
135
|
+
#updateAidaAvailability(aidaAvailability: Host.AidaClient.AidaAccessPreconditions): void {
|
|
136
|
+
if (aidaAvailability !== this.#aidaAvailability) {
|
|
137
|
+
this.#aidaAvailability = aidaAvailability;
|
|
137
138
|
this.requestUpdate();
|
|
138
139
|
}
|
|
139
140
|
}
|
|
140
141
|
|
|
142
|
+
#onAidaAvailabilityChange(ev: Common.EventTarget.EventTargetEvent<Host.AidaClient.AidaAccessPreconditions>): void {
|
|
143
|
+
this.#updateAidaAvailability(ev.data);
|
|
144
|
+
}
|
|
145
|
+
|
|
141
146
|
setLoading(loading: boolean): void {
|
|
142
147
|
this.#loading = loading;
|
|
143
148
|
this.requestUpdate();
|
|
@@ -172,7 +177,10 @@ export class AiCodeCompletionSummaryToolbar extends UI.Widget.Widget {
|
|
|
172
177
|
super.wasShown();
|
|
173
178
|
Host.AidaClient.HostConfigTracker.instance().addEventListener(
|
|
174
179
|
Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#boundOnAidaAvailabilityChange);
|
|
175
|
-
|
|
180
|
+
const initialAvailability = Host.AidaClient.HostConfigTracker.instance().aidaAvailability;
|
|
181
|
+
if (initialAvailability !== undefined) {
|
|
182
|
+
this.#updateAidaAvailability(initialAvailability);
|
|
183
|
+
}
|
|
176
184
|
}
|
|
177
185
|
|
|
178
186
|
override willHide(): void {
|
|
@@ -171,7 +171,8 @@ export class AiCodeCompletionTeaser extends UI.Widget.Widget {
|
|
|
171
171
|
readonly #view: View;
|
|
172
172
|
|
|
173
173
|
#aidaAvailability?: Host.AidaClient.AidaAccessPreconditions;
|
|
174
|
-
#boundOnAidaAvailabilityChange:
|
|
174
|
+
#boundOnAidaAvailabilityChange:
|
|
175
|
+
(ev: Common.EventTarget.EventTargetEvent<Host.AidaClient.AidaAccessPreconditions>) => void;
|
|
175
176
|
#boundOnAiCodeCompletionSettingChanged: () => void;
|
|
176
177
|
#onDetach: () => void;
|
|
177
178
|
#panel?: AiCodeCompletion.AiCodeCompletion.ContextFlavor;
|
|
@@ -211,14 +212,17 @@ export class AiCodeCompletionTeaser extends UI.Widget.Widget {
|
|
|
211
212
|
});
|
|
212
213
|
}
|
|
213
214
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
this.#aidaAvailability = currentAidaAvailability;
|
|
215
|
+
#updateAidaAvailability(aidaAvailability: Host.AidaClient.AidaAccessPreconditions): void {
|
|
216
|
+
if (aidaAvailability !== this.#aidaAvailability) {
|
|
217
|
+
this.#aidaAvailability = aidaAvailability;
|
|
218
218
|
this.requestUpdate();
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
+
#onAidaAvailabilityChange(ev: Common.EventTarget.EventTargetEvent<Host.AidaClient.AidaAccessPreconditions>): void {
|
|
223
|
+
this.#updateAidaAvailability(ev.data);
|
|
224
|
+
}
|
|
225
|
+
|
|
222
226
|
#onAiCodeCompletionSettingChanged(): void {
|
|
223
227
|
if (this.#aiCodeCompletionFreCompletedSetting.get() || this.#aiCodeCompletionTeaserDismissedSetting.get()) {
|
|
224
228
|
this.detach();
|
|
@@ -322,7 +326,10 @@ export class AiCodeCompletionTeaser extends UI.Widget.Widget {
|
|
|
322
326
|
Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#boundOnAidaAvailabilityChange);
|
|
323
327
|
this.#aiCodeCompletionFreCompletedSetting.addChangeListener(this.#boundOnAiCodeCompletionSettingChanged);
|
|
324
328
|
this.#aiCodeCompletionTeaserDismissedSetting.addChangeListener(this.#boundOnAiCodeCompletionSettingChanged);
|
|
325
|
-
|
|
329
|
+
const initialAvailability = Host.AidaClient.HostConfigTracker.instance().aidaAvailability;
|
|
330
|
+
if (initialAvailability !== undefined) {
|
|
331
|
+
this.#updateAidaAvailability(initialAvailability);
|
|
332
|
+
}
|
|
326
333
|
}
|
|
327
334
|
|
|
328
335
|
override willHide(): void {
|
|
@@ -177,7 +177,7 @@ export class GeminiRebrandPromoDialog extends UI.Widget.VBox {
|
|
|
177
177
|
return;
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
const currentAidaAvailability =
|
|
180
|
+
const currentAidaAvailability = Host.AidaClient.HostConfigTracker.instance().aidaAvailability;
|
|
181
181
|
if (currentAidaAvailability !== Host.AidaClient.AidaAccessPreconditions.AVAILABLE) {
|
|
182
182
|
return;
|
|
183
183
|
}
|
|
@@ -409,7 +409,8 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
|
|
|
409
409
|
#isSlow = false;
|
|
410
410
|
#timeoutId: ReturnType<typeof setTimeout>|null = null;
|
|
411
411
|
#aidaAvailability?: Host.AidaClient.AidaAccessPreconditions;
|
|
412
|
-
#boundOnAidaAvailabilityChange:
|
|
412
|
+
#boundOnAidaAvailabilityChange:
|
|
413
|
+
(ev: Common.EventTarget.EventTargetEvent<Host.AidaClient.AidaAccessPreconditions>) => void;
|
|
413
414
|
#boundOnDownloadProgressChange: (event: Common.EventTarget.EventTargetEvent<number>) => void;
|
|
414
415
|
#boundOnSessionCreation: () => void;
|
|
415
416
|
#downloadProgress: number|null = null;
|
|
@@ -448,14 +449,17 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
|
|
|
448
449
|
return Common.Settings.Settings.instance().createLocalSetting('console-insights-onboarding-finished', true);
|
|
449
450
|
}
|
|
450
451
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
this.#aidaAvailability = currentAidaAvailability;
|
|
452
|
+
#updateAidaAvailability(aidaAvailability: Host.AidaClient.AidaAccessPreconditions): void {
|
|
453
|
+
if (aidaAvailability !== this.#aidaAvailability) {
|
|
454
|
+
this.#aidaAvailability = aidaAvailability;
|
|
455
455
|
this.requestUpdate();
|
|
456
456
|
}
|
|
457
457
|
}
|
|
458
458
|
|
|
459
|
+
#onAidaAvailabilityChange(ev: Common.EventTarget.EventTargetEvent<Host.AidaClient.AidaAccessPreconditions>): void {
|
|
460
|
+
this.#updateAidaAvailability(ev.data);
|
|
461
|
+
}
|
|
462
|
+
|
|
459
463
|
#executeConsoleInsightAction(): void {
|
|
460
464
|
UI.Context.Context.instance().setFlavor(ConsoleViewMessage, this.#consoleViewMessage);
|
|
461
465
|
const action = UI.ActionRegistry.ActionRegistry.instance().getAction(EXPLAIN_TEASER_ACTION_ID);
|
|
@@ -731,7 +735,10 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
|
|
|
731
735
|
super.wasShown();
|
|
732
736
|
Host.AidaClient.HostConfigTracker.instance().addEventListener(
|
|
733
737
|
Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#boundOnAidaAvailabilityChange);
|
|
734
|
-
|
|
738
|
+
const initialAvailability = Host.AidaClient.HostConfigTracker.instance().aidaAvailability;
|
|
739
|
+
if (initialAvailability !== undefined) {
|
|
740
|
+
this.#updateAidaAvailability(initialAvailability);
|
|
741
|
+
}
|
|
735
742
|
}
|
|
736
743
|
|
|
737
744
|
override willHide(): void {
|
|
@@ -196,9 +196,9 @@ const UIStrings = {
|
|
|
196
196
|
*/
|
|
197
197
|
copyVisibleStyledSelection: 'Copy visible styled selection',
|
|
198
198
|
/**
|
|
199
|
-
* @description Text to
|
|
199
|
+
* @description Text to resend a network request.
|
|
200
200
|
*/
|
|
201
|
-
|
|
201
|
+
resend: 'Resend',
|
|
202
202
|
/**
|
|
203
203
|
* @description Text to indicate DevTools is writing to a file.
|
|
204
204
|
*/
|
|
@@ -1338,10 +1338,10 @@ export class ConsoleView extends UI.Widget.VBox implements
|
|
|
1338
1338
|
|
|
1339
1339
|
if (consoleMessage) {
|
|
1340
1340
|
const request = Logs.NetworkLog.NetworkLog.requestForConsoleMessage(consoleMessage);
|
|
1341
|
-
if (request && SDK.NetworkManager.NetworkManager.
|
|
1342
|
-
contextMenu.debugSection().appendItem(
|
|
1343
|
-
|
|
1344
|
-
|
|
1341
|
+
if (request && SDK.NetworkManager.NetworkManager.canResendRequest(request)) {
|
|
1342
|
+
contextMenu.debugSection().appendItem(i18nString(UIStrings.resend),
|
|
1343
|
+
SDK.NetworkManager.NetworkManager.replayRequest.bind(null, request),
|
|
1344
|
+
{jslogContext: 'resend'});
|
|
1345
1345
|
}
|
|
1346
1346
|
}
|
|
1347
1347
|
|
|
@@ -19,20 +19,20 @@ const {html, nothing, render} = Lit;
|
|
|
19
19
|
|
|
20
20
|
const UIStrings = {
|
|
21
21
|
/**
|
|
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
|
|
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 Console.
|
|
23
23
|
*/
|
|
24
24
|
sErrors: '{n, plural, =1 {# error} other {# errors}}',
|
|
25
25
|
/**
|
|
26
|
-
* @description The console warning count in the Warning Error Counter shown in the main toolbar (top-left in DevTools). The warning count refers to the number of warnings currently present in the
|
|
26
|
+
* @description The console warning count in the Warning Error Counter shown in the main toolbar (top-left in DevTools). The warning count refers to the number of warnings currently present in the Console.
|
|
27
27
|
*/
|
|
28
28
|
sWarnings: '{n, plural, =1 {# warning} other {# warnings}}',
|
|
29
29
|
/**
|
|
30
|
-
* @description Tooltip shown for a main toolbar button that opens the Console panel
|
|
30
|
+
* @description Tooltip shown for a main toolbar button that opens the Console panel.
|
|
31
31
|
* @example {2 errors, 1 warning} PH1
|
|
32
32
|
*/
|
|
33
33
|
openConsoleToViewS: 'Open Console to view {PH1}',
|
|
34
34
|
/**
|
|
35
|
-
* @description Title for the issues count in the Issues Error Counter shown in the main toolbar (top-left in DevTools). The issues count refers to the number of issues in the
|
|
35
|
+
* @description Title for the issues count in the Issues Error Counter shown in the main toolbar (top-left in DevTools). The issues count refers to the number of issues in the Issues tab.
|
|
36
36
|
*/
|
|
37
37
|
openIssuesToView: '{n, plural, =1 {Open Issues to view # issue:} other {Open Issues to view # issues:}}',
|
|
38
38
|
} as const;
|
|
@@ -61,6 +61,7 @@ export class CoverageModel extends SDK.SDKModel.SDKModel<EventTypes> {
|
|
|
61
61
|
private sourceMapManager: SDK.SourceMapManager.SourceMapManager<SDK.Script.Script>|null;
|
|
62
62
|
private willResolveSourceMaps: boolean;
|
|
63
63
|
private processSourceMapBacklog: SourceMapObject[];
|
|
64
|
+
private isPolling: boolean;
|
|
64
65
|
|
|
65
66
|
constructor(target: SDK.Target.Target) {
|
|
66
67
|
super(target);
|
|
@@ -88,6 +89,7 @@ export class CoverageModel extends SDK.SDKModel.SDKModel<EventTypes> {
|
|
|
88
89
|
this.performanceTraceRecording = false;
|
|
89
90
|
this.willResolveSourceMaps = false;
|
|
90
91
|
this.processSourceMapBacklog = [];
|
|
92
|
+
this.isPolling = false;
|
|
91
93
|
}
|
|
92
94
|
|
|
93
95
|
async start(jsCoveragePerBlock: boolean): Promise<boolean> {
|
|
@@ -184,22 +186,30 @@ export class CoverageModel extends SDK.SDKModel.SDKModel<EventTypes> {
|
|
|
184
186
|
}
|
|
185
187
|
|
|
186
188
|
async startPolling(): Promise<void> {
|
|
187
|
-
if (this.
|
|
189
|
+
if (this.isPolling || this.suspensionState !== SuspensionState.ACTIVE) {
|
|
188
190
|
return;
|
|
189
191
|
}
|
|
192
|
+
this.isPolling = true;
|
|
190
193
|
await this.pollLoop();
|
|
191
194
|
}
|
|
192
195
|
|
|
193
196
|
private async pollLoop(): Promise<void> {
|
|
194
197
|
this.clearTimer();
|
|
198
|
+
if (!this.isPolling) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
195
201
|
this.currentPollPromise = this.pollAndCallback();
|
|
196
202
|
await this.currentPollPromise;
|
|
203
|
+
if (!this.isPolling) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
197
206
|
if (this.suspensionState === SuspensionState.ACTIVE || this.performanceTraceRecording) {
|
|
198
207
|
this.pollTimer = window.setTimeout(() => this.pollLoop(), COVERAGE_POLLING_PERIOD_MS);
|
|
199
208
|
}
|
|
200
209
|
}
|
|
201
210
|
|
|
202
211
|
async stopPolling(): Promise<void> {
|
|
212
|
+
this.isPolling = false;
|
|
203
213
|
this.clearTimer();
|
|
204
214
|
await this.currentPollPromise;
|
|
205
215
|
this.currentPollPromise = null;
|
|
@@ -154,7 +154,7 @@ export class StylePropertiesSection {
|
|
|
154
154
|
private parentsComputedStyles: Map<string, string>|null;
|
|
155
155
|
private computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null;
|
|
156
156
|
editable: boolean;
|
|
157
|
-
private hoverTimer:
|
|
157
|
+
private hoverTimer: ReturnType<typeof setTimeout>|null = null;
|
|
158
158
|
private willCauseCancelEditing = false;
|
|
159
159
|
private forceShowAll = false;
|
|
160
160
|
private readonly originalPropertiesCount: number;
|
|
@@ -275,7 +275,11 @@ export class StylePropertiesSection {
|
|
|
275
275
|
this.selectorElement.classList.add('selector');
|
|
276
276
|
this.selectorElement.textContent = headerText;
|
|
277
277
|
selectorContainer.appendChild(this.selectorElement);
|
|
278
|
-
this.selectorElement.addEventListener('mouseenter', () =>
|
|
278
|
+
this.selectorElement.addEventListener('mouseenter', () => {
|
|
279
|
+
if (this.styleInternal.parentRule instanceof SDK.CSSRule.CSSStyleRule) {
|
|
280
|
+
this.onMouseEnterSelector(this.styleInternal.parentRule);
|
|
281
|
+
}
|
|
282
|
+
}, false);
|
|
279
283
|
this.selectorElement.addEventListener('mouseleave', this.onMouseOutSelector.bind(this), false);
|
|
280
284
|
this.#specificityTooltips = selectorContainer.createChild('span');
|
|
281
285
|
|
|
@@ -679,35 +683,31 @@ export class StylePropertiesSection {
|
|
|
679
683
|
SDK.OverlayModel.OverlayModel.hideDOMNodeHighlight(SDK.TargetManager.TargetManager.instance());
|
|
680
684
|
}
|
|
681
685
|
|
|
682
|
-
private onMouseEnterSelector(
|
|
686
|
+
private onMouseEnterSelector(rule: SDK.CSSRule.CSSStyleRule, nestingIndex?: number): void {
|
|
683
687
|
if (this.hoverTimer) {
|
|
684
688
|
clearTimeout(this.hoverTimer);
|
|
685
689
|
}
|
|
686
|
-
|
|
690
|
+
const selectorList = constructResolvedSelector(rule, nestingIndex);
|
|
691
|
+
if (!selectorList) {
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
this.hoverTimer = setTimeout(this.highlight.bind(this, undefined, selectorList), 300);
|
|
687
695
|
}
|
|
688
696
|
|
|
689
697
|
/**
|
|
690
698
|
* Highlights the DOM node associated with this style section in the page overlay.
|
|
691
|
-
* Use `
|
|
692
|
-
* rule or selector
|
|
699
|
+
* Use `selectorList` to highlight elements matching a specific parent/ancestor
|
|
700
|
+
* rule or selector.
|
|
693
701
|
*
|
|
694
702
|
* @param mode Highlight mode (defaults to `'all'`).
|
|
695
|
-
* @param
|
|
703
|
+
* @param selectorList Parent selector string to highlight.
|
|
696
704
|
*/
|
|
697
|
-
highlight(mode: string|undefined = 'all',
|
|
705
|
+
highlight(mode: string|undefined = 'all', selectorList: string): void {
|
|
698
706
|
SDK.OverlayModel.OverlayModel.hideDOMNodeHighlight(SDK.TargetManager.TargetManager.instance());
|
|
699
707
|
const node = this.stylesContainer.node();
|
|
700
708
|
if (!node) {
|
|
701
709
|
return;
|
|
702
710
|
}
|
|
703
|
-
let selectorList: string|undefined;
|
|
704
|
-
if (typeof ruleOrSelector === 'string') {
|
|
705
|
-
selectorList = ruleOrSelector;
|
|
706
|
-
} else if (ruleOrSelector instanceof SDK.CSSRule.CSSStyleRule) {
|
|
707
|
-
selectorList = ruleOrSelector.selectorText();
|
|
708
|
-
} else if (this.styleInternal.parentRule instanceof SDK.CSSRule.CSSStyleRule) {
|
|
709
|
-
selectorList = this.styleInternal.parentRule.selectorText();
|
|
710
|
-
}
|
|
711
711
|
node.domModel().overlayModel().highlightInOverlay({node, selectorList}, mode);
|
|
712
712
|
}
|
|
713
713
|
|
|
@@ -1164,7 +1164,7 @@ export class StylePropertiesSection {
|
|
|
1164
1164
|
}
|
|
1165
1165
|
|
|
1166
1166
|
const nestingElement = document.createElement('div');
|
|
1167
|
-
nestingElement.addEventListener('mouseenter', () => this.onMouseEnterSelector(
|
|
1167
|
+
nestingElement.addEventListener('mouseenter', () => this.onMouseEnterSelector(rule, nestingIndex), false);
|
|
1168
1168
|
nestingElement.addEventListener('mouseleave', this.onMouseOutSelector.bind(this), false);
|
|
1169
1169
|
nestingElement.textContent = `${nestingSelector} {`;
|
|
1170
1170
|
return nestingElement;
|
|
@@ -2273,3 +2273,36 @@ export class HighlightPseudoStylePropertiesSection extends StylePropertiesSectio
|
|
|
2273
2273
|
interface TreeElementParent {
|
|
2274
2274
|
appendChild(child: UI.TreeOutline.TreeElement): void;
|
|
2275
2275
|
}
|
|
2276
|
+
|
|
2277
|
+
export function constructResolvedSelector(rule: SDK.CSSRule.CSSRule|null, nestingIndex?: number): string|undefined {
|
|
2278
|
+
if (!(rule instanceof SDK.CSSRule.CSSStyleRule)) {
|
|
2279
|
+
return undefined;
|
|
2280
|
+
}
|
|
2281
|
+
|
|
2282
|
+
const nestingSelectors = rule.nestingSelectors;
|
|
2283
|
+
if (!nestingSelectors) {
|
|
2284
|
+
return nestingIndex === undefined ? rule.selectorText() : undefined;
|
|
2285
|
+
}
|
|
2286
|
+
|
|
2287
|
+
if (nestingIndex !== undefined && (nestingIndex < 0 || nestingIndex >= nestingSelectors.length)) {
|
|
2288
|
+
return undefined;
|
|
2289
|
+
}
|
|
2290
|
+
|
|
2291
|
+
const selectorText = nestingIndex !== undefined ? nestingSelectors[nestingIndex] : rule.selectorText();
|
|
2292
|
+
|
|
2293
|
+
const parentIndex = nestingIndex !== undefined ? nestingIndex + 1 : 0;
|
|
2294
|
+
const parentSelector = constructResolvedSelector(rule, parentIndex);
|
|
2295
|
+
|
|
2296
|
+
if (!parentSelector) {
|
|
2297
|
+
return selectorText;
|
|
2298
|
+
}
|
|
2299
|
+
|
|
2300
|
+
// Strip pseudo-elements (e.g. ::before) because pseudo-elements are invalid inside CSS :is(...).
|
|
2301
|
+
const sanitizedParent = parentSelector.replace(/::[a-zA-Z-]+/g, '').trim();
|
|
2302
|
+
|
|
2303
|
+
if (selectorText.includes('&')) {
|
|
2304
|
+
return selectorText.replaceAll('&', `:is(${sanitizedParent})`);
|
|
2305
|
+
}
|
|
2306
|
+
|
|
2307
|
+
return `:is(${sanitizedParent}) ${selectorText.trim()}`;
|
|
2308
|
+
}
|
|
@@ -29,17 +29,29 @@ export class StylesAiCodeCompletionProvider {
|
|
|
29
29
|
sampleId?: number,
|
|
30
30
|
}|null) => void;
|
|
31
31
|
|
|
32
|
-
#
|
|
32
|
+
#boundOnAidaAvailabilityChange =
|
|
33
|
+
(ev: Common.EventTarget.EventTargetEvent<Host.AidaClient.AidaAccessPreconditions>): void => {
|
|
34
|
+
this.#updateAiCodeCompletionStateWithAvailability(ev.data);
|
|
35
|
+
};
|
|
36
|
+
#boundOnSettingChange = (): void => {
|
|
37
|
+
const aidaAvailability = Host.AidaClient.HostConfigTracker.instance().aidaAvailability;
|
|
38
|
+
if (aidaAvailability !== undefined) {
|
|
39
|
+
this.#updateAiCodeCompletionStateWithAvailability(aidaAvailability);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
33
42
|
|
|
34
43
|
private constructor(aiCodeCompletionConfig: TextEditor.AiCodeCompletionProvider.AiCodeCompletionConfig) {
|
|
35
44
|
if (!AiCodeCompletion.AiCodeCompletion.AiCodeCompletion.isAiCodeCompletionStylesAvailable()) {
|
|
36
45
|
throw new Error('AI code completion feature in Styles is not available.');
|
|
37
46
|
}
|
|
38
47
|
this.#aiCodeCompletionConfig = aiCodeCompletionConfig;
|
|
39
|
-
Host.AidaClient.HostConfigTracker.instance().addEventListener(
|
|
40
|
-
|
|
41
|
-
this.#aiCodeCompletionSetting.addChangeListener(this.#
|
|
42
|
-
|
|
48
|
+
Host.AidaClient.HostConfigTracker.instance().addEventListener(Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED,
|
|
49
|
+
this.#boundOnAidaAvailabilityChange);
|
|
50
|
+
this.#aiCodeCompletionSetting.addChangeListener(this.#boundOnSettingChange);
|
|
51
|
+
const initialAvailability = Host.AidaClient.HostConfigTracker.instance().aidaAvailability;
|
|
52
|
+
if (initialAvailability !== undefined) {
|
|
53
|
+
this.#updateAiCodeCompletionStateWithAvailability(initialAvailability);
|
|
54
|
+
}
|
|
43
55
|
}
|
|
44
56
|
|
|
45
57
|
static createInstance(aiCodeCompletionConfig: TextEditor.AiCodeCompletionProvider.AiCodeCompletionConfig):
|
|
@@ -78,8 +90,7 @@ export class StylesAiCodeCompletionProvider {
|
|
|
78
90
|
this.#aiCodeCompletionConfig?.onFeatureDisabled();
|
|
79
91
|
}
|
|
80
92
|
|
|
81
|
-
|
|
82
|
-
const aidaAvailability = await Host.AidaClient.AidaClient.checkAccessPreconditions();
|
|
93
|
+
#updateAiCodeCompletionStateWithAvailability(aidaAvailability: Host.AidaClient.AidaAccessPreconditions): void {
|
|
83
94
|
const isAvailable = aidaAvailability === Host.AidaClient.AidaAccessPreconditions.AVAILABLE;
|
|
84
95
|
const devtoolsLocale = i18n.DevToolsLocale.DevToolsLocale.instance().locale;
|
|
85
96
|
const isEnabled =
|
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
import type * as Common from '../../core/common/common.js';
|
|
7
7
|
import * as Host from '../../core/host/host.js';
|
|
8
|
+
import type * as Foundation from '../../foundation/foundation.js';
|
|
8
9
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
9
10
|
import * as ThemeSupport from '../../ui/legacy/theme_support/theme_support.js';
|
|
10
11
|
|
|
11
12
|
import {DeviceModeWrapper} from './DeviceModeWrapper.js';
|
|
12
13
|
import {type Bounds, Events, InspectedPagePlaceholder} from './InspectedPagePlaceholder.js';
|
|
13
14
|
|
|
14
|
-
let appInstance: AdvancedApp;
|
|
15
|
+
let appInstance: AdvancedApp|null = null;
|
|
15
16
|
|
|
16
17
|
export class AdvancedApp implements UI.App.App {
|
|
17
18
|
private rootSplitWidget!: UI.SplitWidget.SplitWidget;
|
|
@@ -20,8 +21,10 @@ export class AdvancedApp implements UI.App.App {
|
|
|
20
21
|
private toolboxWindow?: Window|null;
|
|
21
22
|
private toolboxRootView?: UI.RootView.RootView;
|
|
22
23
|
private changingDockSide?: boolean;
|
|
24
|
+
readonly #universe: Foundation.Universe.Universe;
|
|
23
25
|
|
|
24
|
-
constructor() {
|
|
26
|
+
constructor(universe: Foundation.Universe.Universe) {
|
|
27
|
+
this.#universe = universe;
|
|
25
28
|
UI.DockController.DockController.instance().addEventListener(
|
|
26
29
|
UI.DockController.Events.BEFORE_DOCK_SIDE_CHANGED, this.openToolboxWindow, this);
|
|
27
30
|
}
|
|
@@ -29,15 +32,22 @@ export class AdvancedApp implements UI.App.App {
|
|
|
29
32
|
/**
|
|
30
33
|
* Note: it's used by toolbox.ts without real type checks.
|
|
31
34
|
*/
|
|
32
|
-
static instance(): AdvancedApp {
|
|
35
|
+
static instance(universe?: Foundation.Universe.Universe): AdvancedApp {
|
|
33
36
|
if (!appInstance) {
|
|
34
|
-
|
|
37
|
+
if (!universe) {
|
|
38
|
+
throw new Error('AdvancedApp.instance() requires a Universe on initial instantiation');
|
|
39
|
+
}
|
|
40
|
+
appInstance = new AdvancedApp(universe);
|
|
35
41
|
}
|
|
36
42
|
return appInstance;
|
|
37
43
|
}
|
|
38
44
|
|
|
45
|
+
static removeInstance(): void {
|
|
46
|
+
appInstance = null;
|
|
47
|
+
}
|
|
48
|
+
|
|
39
49
|
presentUI(document: Document): void {
|
|
40
|
-
const rootView = new UI.RootView.RootView();
|
|
50
|
+
const rootView = new UI.RootView.RootView(this.#universe);
|
|
41
51
|
|
|
42
52
|
this.rootSplitWidget =
|
|
43
53
|
new UI.SplitWidget.SplitWidget(false, true, 'inspector-view.split-view-state', 555, 300, true);
|
|
@@ -85,7 +95,7 @@ export class AdvancedApp implements UI.App.App {
|
|
|
85
95
|
UI.UIUtils.installComponentRootStyles(toolboxDocument.body);
|
|
86
96
|
UI.ContextMenu.ContextMenu.installHandler(toolboxDocument);
|
|
87
97
|
|
|
88
|
-
this.toolboxRootView = new UI.RootView.RootView();
|
|
98
|
+
this.toolboxRootView = new UI.RootView.RootView(this.#universe);
|
|
89
99
|
this.toolboxRootView.attachToDocument(toolboxDocument);
|
|
90
100
|
|
|
91
101
|
this.updateDeviceModeView();
|
|
@@ -200,7 +210,7 @@ export class AdvancedAppProvider implements UI.AppProvider.AppProvider {
|
|
|
200
210
|
return advancedAppProviderInstance;
|
|
201
211
|
}
|
|
202
212
|
|
|
203
|
-
createApp(): UI.App.App {
|
|
204
|
-
return AdvancedApp.instance();
|
|
213
|
+
createApp(universe: Foundation.Universe.Universe): UI.App.App {
|
|
214
|
+
return AdvancedApp.instance(universe);
|
|
205
215
|
}
|
|
206
216
|
}
|
|
@@ -21,31 +21,31 @@ import eventListenersViewStyles from './eventListenersView.css.js';
|
|
|
21
21
|
|
|
22
22
|
const UIStrings = {
|
|
23
23
|
/**
|
|
24
|
-
* @description Empty holder text content in Event Listeners
|
|
24
|
+
* @description Empty holder text content in Event Listeners view of the Event Listeners sidebar in the Sources panel.
|
|
25
25
|
*/
|
|
26
26
|
noEventListeners: 'No event listeners',
|
|
27
27
|
/**
|
|
28
|
-
* @description Empty holder text content in Event Listeners
|
|
28
|
+
* @description Empty holder text content in Event Listeners view of the Event Listeners sidebar in the Elements panel.
|
|
29
29
|
*/
|
|
30
30
|
eventListenersExplanation: 'On this page you will find registered event listeners',
|
|
31
31
|
/**
|
|
32
|
-
* @description Delete button title in Event Listeners
|
|
32
|
+
* @description Delete button title in Event Listeners view of the Event Listeners sidebar in the Sources panel.
|
|
33
33
|
*/
|
|
34
34
|
deleteEventListener: 'Delete event listener',
|
|
35
35
|
/**
|
|
36
|
-
* @description Passive button text content in Event Listeners
|
|
36
|
+
* @description Passive button text content in Event Listeners view of the Event Listeners sidebar in the Sources panel.
|
|
37
37
|
*/
|
|
38
|
-
togglePassive: 'Toggle
|
|
38
|
+
togglePassive: 'Toggle passive',
|
|
39
39
|
/**
|
|
40
|
-
* @description Passive button title in Event Listeners
|
|
40
|
+
* @description Passive button title in Event Listeners view of the Event Listeners sidebar in the Sources panel.
|
|
41
41
|
*/
|
|
42
42
|
toggleWhetherEventListenerIs: 'Toggle whether event listener is passive or blocking',
|
|
43
43
|
/**
|
|
44
|
-
* @description A context menu item to reveal a node in the DOM tree of the Elements
|
|
44
|
+
* @description A context menu item to reveal a node in the DOM tree of the Elements panel.
|
|
45
45
|
*/
|
|
46
46
|
openInElementsPanel: 'Open in Elements panel',
|
|
47
47
|
/**
|
|
48
|
-
* @description Text in Event Listeners
|
|
48
|
+
* @description Text in Event Listeners widget of the Elements panel.
|
|
49
49
|
*/
|
|
50
50
|
passive: 'Passive',
|
|
51
51
|
} as const;
|
|
@@ -753,7 +753,8 @@ export type ViewFunction = typeof DEFAULT_VIEW;
|
|
|
753
753
|
|
|
754
754
|
export class ConsoleInsight extends UI.Widget.Widget {
|
|
755
755
|
static async create(promptBuilder: PublicPromptBuilder, aidaClient: PublicAidaClient): Promise<Lit.LitTemplate> {
|
|
756
|
-
const aidaPreconditions =
|
|
756
|
+
const aidaPreconditions = Host.AidaClient.HostConfigTracker.instance().aidaAvailability ??
|
|
757
|
+
await Host.AidaClient.AidaClient.checkAccessPreconditions();
|
|
757
758
|
return html`<devtools-widget class="devtools-console-insight" ${
|
|
758
759
|
widget(element => new ConsoleInsight(promptBuilder, aidaClient, aidaPreconditions, element))}>
|
|
759
760
|
</devtools-widget>`;
|
|
@@ -780,7 +781,8 @@ export class ConsoleInsight extends UI.Widget.Widget {
|
|
|
780
781
|
|
|
781
782
|
#consoleInsightsEnabledSetting: Common.Settings.Setting<boolean>|undefined;
|
|
782
783
|
#aidaPreconditions: Host.AidaClient.AidaAccessPreconditions;
|
|
783
|
-
#boundOnAidaAvailabilityChange:
|
|
784
|
+
#boundOnAidaAvailabilityChange:
|
|
785
|
+
(ev: Common.EventTarget.EventTargetEvent<Host.AidaClient.AidaAccessPreconditions>) => void;
|
|
784
786
|
#marked: Marked.Marked.Marked;
|
|
785
787
|
|
|
786
788
|
constructor(
|
|
@@ -885,7 +887,10 @@ export class ConsoleInsight extends UI.Widget.Widget {
|
|
|
885
887
|
Host.AidaClient.HostConfigTracker.instance().addEventListener(
|
|
886
888
|
Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#boundOnAidaAvailabilityChange);
|
|
887
889
|
// If AIDA availability has changed while the component was disconnected, we need to update.
|
|
888
|
-
|
|
890
|
+
const initialAvailability = Host.AidaClient.HostConfigTracker.instance().aidaAvailability;
|
|
891
|
+
if (initialAvailability !== undefined) {
|
|
892
|
+
this.#updateAidaAvailability(initialAvailability);
|
|
893
|
+
}
|
|
889
894
|
// The setting might have been turned on/off while the component was disconnected.
|
|
890
895
|
// Update the state, unless the current state is already terminal (`INSIGHT` or `ERROR`).
|
|
891
896
|
if (this.#state.type !== State.INSIGHT && this.#state.type !== State.ERROR) {
|
|
@@ -901,15 +906,18 @@ export class ConsoleInsight extends UI.Widget.Widget {
|
|
|
901
906
|
Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#boundOnAidaAvailabilityChange);
|
|
902
907
|
}
|
|
903
908
|
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
this.#aidaPreconditions = currentAidaAvailability;
|
|
909
|
+
#updateAidaAvailability(aidaAvailability: Host.AidaClient.AidaAccessPreconditions): void {
|
|
910
|
+
if (aidaAvailability !== this.#aidaPreconditions) {
|
|
911
|
+
this.#aidaPreconditions = aidaAvailability;
|
|
908
912
|
this.#state = this.#getStateFromAidaAvailability();
|
|
909
913
|
void this.#generateInsightIfNeeded();
|
|
910
914
|
}
|
|
911
915
|
}
|
|
912
916
|
|
|
917
|
+
#onAidaAvailabilityChange(ev: Common.EventTarget.EventTargetEvent<Host.AidaClient.AidaAccessPreconditions>): void {
|
|
918
|
+
this.#updateAidaAvailability(ev.data);
|
|
919
|
+
}
|
|
920
|
+
|
|
913
921
|
#onConsoleInsightsSettingChanged(): void {
|
|
914
922
|
if (this.#consoleInsightsEnabledSetting?.getIfNotDisabled() === true) {
|
|
915
923
|
this.#getOnboardingCompletedSetting().set(true);
|