chrome-devtools-frontend 1.0.1553956 → 1.0.1555430
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/Images/src/spark.svg +10 -0
- package/front_end/core/protocol_client/InspectorBackend.ts +1 -1
- package/front_end/core/root/Runtime.ts +0 -4
- package/front_end/core/sdk/DOMModel.ts +101 -7
- package/front_end/core/sdk/ResourceTreeModel.ts +0 -1
- package/front_end/generated/SupportedCSSProperties.js +18 -0
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +1 -1
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +1 -1
- package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +1 -1
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +1 -1
- package/front_end/{ui/components → models}/annotations/AnnotationRepository.ts +3 -3
- package/front_end/models/annotations/README.md +7 -0
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +8 -0
- package/front_end/models/javascript_metadata/NativeFunctions.js +15 -23
- package/front_end/models/stack_trace/StackTrace.ts +13 -2
- package/front_end/models/stack_trace/StackTraceImpl.ts +81 -6
- package/front_end/models/stack_trace/StackTraceModel.ts +35 -3
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +45 -4
- package/front_end/panels/ai_assistance/components/ArtifactsViewer.ts +57 -0
- package/front_end/panels/ai_assistance/components/ChatView.ts +1 -0
- package/front_end/panels/ai_assistance/components/artifactsViewer.css +10 -0
- package/front_end/panels/application/BounceTrackingMitigationsTreeElement.ts +2 -6
- package/front_end/panels/application/components/BounceTrackingMitigationsView.ts +133 -118
- package/front_end/panels/application/preloading/PreloadingView.ts +12 -6
- package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +230 -237
- package/front_end/panels/application/preloading/components/PreloadingGrid.ts +96 -79
- package/front_end/panels/application/preloading/components/preloadingGrid.css +26 -29
- package/front_end/panels/application/preloading/preloadingView.css +6 -0
- package/front_end/panels/common/Annotation.ts +1 -1
- package/front_end/panels/common/AnnotationManager.ts +1 -1
- package/front_end/panels/common/ExtensionView.ts +1 -0
- package/front_end/panels/console/ConsoleContextSelector.ts +74 -9
- package/front_end/panels/console/consoleContextSelector.css +31 -29
- package/front_end/panels/coverage/coverageListView.css +59 -57
- package/front_end/panels/elements/ElementsPanel.ts +1 -1
- package/front_end/panels/elements/ElementsTreeElement.ts +39 -1
- package/front_end/panels/elements/ElementsTreeOutline.ts +23 -21
- package/front_end/panels/elements/TopLayerContainer.ts +26 -91
- package/front_end/panels/explain/components/ConsoleInsight.ts +3 -3
- package/front_end/panels/network/NetworkItemView.ts +1 -1
- package/front_end/panels/network/NetworkLogView.ts +1 -1
- package/front_end/panels/network/NetworkPanel.ts +1 -1
- package/front_end/panels/recorder/RecorderController.ts +0 -1
- package/front_end/panels/security/CookieControlsView.ts +21 -10
- package/front_end/panels/security/SecurityPanelSidebar.ts +5 -0
- package/front_end/panels/timeline/CompatibilityTracksAppender.ts +0 -1
- package/front_end/panels/timeline/TimelineUIUtils.ts +5 -8
- package/front_end/panels/timeline/components/Sidebar.ts +16 -7
- package/front_end/panels/timeline/components/SidebarInsightsTab.ts +169 -129
- package/front_end/panels/timeline/components/TimelineSummary.ts +75 -54
- package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +16 -25
- package/front_end/panels/timeline/components/insights/Cache.ts +12 -8
- package/front_end/panels/timeline/components/insights/Checklist.ts +53 -43
- package/front_end/panels/timeline/components/insights/DOMSize.ts +25 -21
- package/front_end/panels/timeline/components/insights/DocumentLatency.ts +6 -3
- package/front_end/panels/timeline/components/insights/DuplicatedJavaScript.ts +7 -7
- package/front_end/panels/timeline/components/insights/FontDisplay.ts +7 -5
- package/front_end/panels/timeline/components/insights/ForcedReflow.ts +11 -9
- package/front_end/panels/timeline/components/insights/INPBreakdown.ts +7 -6
- package/front_end/panels/timeline/components/insights/ImageDelivery.ts +7 -5
- package/front_end/panels/timeline/components/insights/InsightRenderer.ts +20 -18
- package/front_end/panels/timeline/components/insights/LCPBreakdown.ts +12 -12
- package/front_end/panels/timeline/components/insights/LCPDiscovery.ts +7 -3
- package/front_end/panels/timeline/components/insights/LegacyJavaScript.ts +7 -7
- package/front_end/panels/timeline/components/insights/ModernHTTP.ts +7 -5
- package/front_end/panels/timeline/components/insights/NetworkDependencyTree.ts +15 -13
- package/front_end/panels/timeline/components/insights/RenderBlocking.ts +2 -2
- package/front_end/panels/timeline/components/insights/SlowCSSSelector.ts +15 -14
- package/front_end/panels/timeline/components/insights/Table.ts +152 -130
- package/front_end/panels/timeline/components/insights/ThirdParties.ts +11 -9
- package/front_end/panels/timeline/components/sidebarInsightsTab.css +50 -48
- package/front_end/panels/timeline/components/timelineSummary.css +58 -57
- package/front_end/panels/timeline/thirdPartyTreeView.css +109 -0
- package/front_end/panels/timeline/timelineDetailsView.css +2 -4
- package/front_end/panels/timeline/timelinePanel.css +0 -110
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/components/settings/SettingCheckbox.ts +4 -6
- package/front_end/ui/legacy/TabbedPane.ts +20 -13
- package/front_end/ui/legacy/ViewManager.ts +2 -32
- package/front_end/ui/legacy/Widget.ts +1 -3
- package/front_end/ui/legacy/tabbedPane.css +4 -7
- package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
- package/package.json +1 -1
- /package/front_end/{ui/components → models}/annotations/AnnotationType.ts +0 -0
- /package/front_end/{ui/components → models}/annotations/annotations.ts +0 -0
|
@@ -7,7 +7,14 @@ import type * as Protocol from '../../generated/protocol.js';
|
|
|
7
7
|
|
|
8
8
|
// eslint-disable-next-line @devtools/es-modules-import
|
|
9
9
|
import * as StackTrace from './stack_trace.js';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
type AnyStackTraceImpl,
|
|
12
|
+
AsyncFragmentImpl,
|
|
13
|
+
DebuggableFragmentImpl,
|
|
14
|
+
FragmentImpl,
|
|
15
|
+
FrameImpl,
|
|
16
|
+
StackTraceImpl
|
|
17
|
+
} from './StackTraceImpl.js';
|
|
11
18
|
import {type FrameNode, type RawFrame, Trie} from './Trie.js';
|
|
12
19
|
|
|
13
20
|
/**
|
|
@@ -45,10 +52,21 @@ export class StackTraceModel extends SDK.SDKModel.SDKModel<unknown> {
|
|
|
45
52
|
return new StackTraceImpl(syncFragment, asyncFragments);
|
|
46
53
|
}
|
|
47
54
|
|
|
55
|
+
async createFromDebuggerPaused(
|
|
56
|
+
pausedDetails: SDK.DebuggerModel.DebuggerPausedDetails,
|
|
57
|
+
rawFramesToUIFrames: TranslateRawFrames): Promise<StackTrace.StackTrace.DebuggableStackTrace> {
|
|
58
|
+
const [syncFragment, asyncFragments] = await Promise.all([
|
|
59
|
+
this.#createDebuggableFragment(pausedDetails, rawFramesToUIFrames),
|
|
60
|
+
this.#createAsyncFragments(pausedDetails, rawFramesToUIFrames),
|
|
61
|
+
]);
|
|
62
|
+
|
|
63
|
+
return new StackTraceImpl(syncFragment, asyncFragments);
|
|
64
|
+
}
|
|
65
|
+
|
|
48
66
|
/** Trigger re-translation of all fragments with the provide script in their call stack */
|
|
49
67
|
async scriptInfoChanged(script: SDK.Script.Script, translateRawFrames: TranslateRawFrames): Promise<void> {
|
|
50
68
|
const translatePromises: Array<Promise<unknown>> = [];
|
|
51
|
-
let stackTracesToUpdate = new Set<
|
|
69
|
+
let stackTracesToUpdate = new Set<AnyStackTraceImpl>();
|
|
52
70
|
|
|
53
71
|
for (const fragment of this.#affectedFragments(script)) {
|
|
54
72
|
// We trigger re-translation only for fragments of leaf-nodes. Any fragment along the ancestor-chain
|
|
@@ -75,8 +93,22 @@ export class StackTraceModel extends SDK.SDKModel.SDKModel<unknown> {
|
|
|
75
93
|
return fragment;
|
|
76
94
|
}
|
|
77
95
|
|
|
96
|
+
async #createDebuggableFragment(
|
|
97
|
+
pausedDetails: SDK.DebuggerModel.DebuggerPausedDetails,
|
|
98
|
+
rawFramesToUIFrames: TranslateRawFrames): Promise<DebuggableFragmentImpl> {
|
|
99
|
+
const fragment = this.#createFragment(pausedDetails.callFrames.map(frame => ({
|
|
100
|
+
scriptId: frame.script.scriptId,
|
|
101
|
+
url: frame.script.sourceURL,
|
|
102
|
+
functionName: frame.functionName,
|
|
103
|
+
lineNumber: frame.location().lineNumber,
|
|
104
|
+
columnNumber: frame.location().columnNumber,
|
|
105
|
+
})));
|
|
106
|
+
await this.#translateFragment(fragment, rawFramesToUIFrames);
|
|
107
|
+
return new DebuggableFragmentImpl(fragment, pausedDetails.callFrames);
|
|
108
|
+
}
|
|
109
|
+
|
|
78
110
|
async #createAsyncFragments(
|
|
79
|
-
stackTraceOrPausedEvent: Protocol.Runtime.StackTrace|
|
|
111
|
+
stackTraceOrPausedEvent: Protocol.Runtime.StackTrace|SDK.DebuggerModel.DebuggerPausedDetails,
|
|
80
112
|
rawFramesToUIFrames: TranslateRawFrames): Promise<AsyncFragmentImpl[]> {
|
|
81
113
|
const asyncFragments: AsyncFragmentImpl[] = [];
|
|
82
114
|
const translatePromises: Array<Promise<unknown>> = [];
|
|
@@ -12,10 +12,10 @@ import * as Root from '../../core/root/root.js';
|
|
|
12
12
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
13
13
|
import * as Protocol from '../../generated/protocol.js';
|
|
14
14
|
import * as AiAssistanceModel from '../../models/ai_assistance/ai_assistance.js';
|
|
15
|
+
import * as Annotations from '../../models/annotations/annotations.js';
|
|
15
16
|
import * as Badges from '../../models/badges/badges.js';
|
|
16
17
|
import * as TextUtils from '../../models/text_utils/text_utils.js';
|
|
17
18
|
import * as Workspace from '../../models/workspace/workspace.js';
|
|
18
|
-
import * as Annotations from '../../ui/components/annotations/annotations.js';
|
|
19
19
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
20
20
|
import * as Snackbars from '../../ui/components/snackbars/snackbars.js';
|
|
21
21
|
import * as UIHelpers from '../../ui/helpers/helpers.js';
|
|
@@ -27,6 +27,7 @@ import * as NetworkPanel from '../network/network.js';
|
|
|
27
27
|
import * as TimelinePanel from '../timeline/timeline.js';
|
|
28
28
|
|
|
29
29
|
import aiAssistancePanelStyles from './aiAssistancePanel.css.js';
|
|
30
|
+
import {ArtifactsViewer} from './components/ArtifactsViewer.js';
|
|
30
31
|
import {
|
|
31
32
|
type AnswerPart,
|
|
32
33
|
type ChatMessage,
|
|
@@ -294,6 +295,8 @@ interface ToolbarViewInput {
|
|
|
294
295
|
onExportConversationClick: () => void;
|
|
295
296
|
onHelpClick: () => void;
|
|
296
297
|
onSettingsClick: () => void;
|
|
298
|
+
onArtifactsSidebarToggle: () => void;
|
|
299
|
+
artifactsSidebarVisible: boolean;
|
|
297
300
|
isLoading: boolean;
|
|
298
301
|
showChatActions: boolean;
|
|
299
302
|
showActiveConversationActions: boolean;
|
|
@@ -386,6 +389,13 @@ function toolbarView(input: ToolbarViewInput): Lit.LitTemplate {
|
|
|
386
389
|
.jslogContext=${'freestyler.settings'}
|
|
387
390
|
.variant=${Buttons.Button.Variant.TOOLBAR}
|
|
388
391
|
@click=${input.onSettingsClick}></devtools-button>
|
|
392
|
+
<!-- If the green experiment is enabled, render the artifacts sidebar toggle button -->
|
|
393
|
+
${Root.Runtime.hostConfig.devToolsGreenDevUi?.enabled ? html`<devtools-button
|
|
394
|
+
title=${i18nString(UIStrings.settings)}
|
|
395
|
+
aria-label=${i18nString(UIStrings.settings)}
|
|
396
|
+
.iconName=${input.artifactsSidebarVisible ? 'left-panel-open' : 'left-panel-close'}
|
|
397
|
+
.variant=${Buttons.Button.Variant.TOOLBAR}
|
|
398
|
+
@click=${input.onArtifactsSidebarToggle}></devtools-button>` : Lit.nothing}
|
|
389
399
|
</devtools-toolbar>
|
|
390
400
|
</div>
|
|
391
401
|
`;
|
|
@@ -396,8 +406,9 @@ function defaultView(input: ViewInput, output: PanelViewOutput, target: HTMLElem
|
|
|
396
406
|
// clang-format off
|
|
397
407
|
function renderState(): Lit.TemplateResult {
|
|
398
408
|
switch (input.state) {
|
|
399
|
-
case ViewState.CHAT_VIEW:
|
|
400
|
-
|
|
409
|
+
case ViewState.CHAT_VIEW: {
|
|
410
|
+
const aiChatView = html`
|
|
411
|
+
<devtools-ai-chat-view
|
|
401
412
|
.props=${input.props}
|
|
402
413
|
${Lit.Directives.ref((el: Element | undefined) => {
|
|
403
414
|
if (!el || !(el instanceof ChatView)) {
|
|
@@ -407,6 +418,30 @@ function defaultView(input: ViewInput, output: PanelViewOutput, target: HTMLElem
|
|
|
407
418
|
output.chatView = el;
|
|
408
419
|
})}
|
|
409
420
|
></devtools-ai-chat-view>`;
|
|
421
|
+
// If the green experiment is enabled, render the chat view inside
|
|
422
|
+
// a split view to also have an artifacts viewer sidebar.
|
|
423
|
+
if(Root.Runtime.hostConfig.devToolsGreenDevUi?.enabled) {
|
|
424
|
+
return html`
|
|
425
|
+
<devtools-split-view
|
|
426
|
+
direction="column"
|
|
427
|
+
sidebar-visibility=${input.props.isArtifactsSidebarOpen ? 'visible' : 'hidden'}
|
|
428
|
+
sidebar-position="second"
|
|
429
|
+
style="width: 100%;"
|
|
430
|
+
>
|
|
431
|
+
<div slot="main">
|
|
432
|
+
${aiChatView}
|
|
433
|
+
</div>
|
|
434
|
+
<div slot="sidebar">
|
|
435
|
+
<devtools-widget
|
|
436
|
+
class="fill-panel"
|
|
437
|
+
.widgetConfig=${UI.Widget.widgetConfig(ArtifactsViewer)}
|
|
438
|
+
></devtools-widget>
|
|
439
|
+
</div>
|
|
440
|
+
</devtools-split-view>`;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
return aiChatView;
|
|
444
|
+
}
|
|
410
445
|
case ViewState.EXPLORE_VIEW:
|
|
411
446
|
return html`<devtools-widget
|
|
412
447
|
class="fill-panel"
|
|
@@ -482,7 +517,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
482
517
|
#selectedElement: AiAssistanceModel.StylingAgent.NodeContext|null = null;
|
|
483
518
|
#selectedPerformanceTrace: AiAssistanceModel.PerformanceAgent.PerformanceTraceContext|null = null;
|
|
484
519
|
#selectedRequest: AiAssistanceModel.NetworkAgent.RequestContext|null = null;
|
|
485
|
-
|
|
520
|
+
#isArtifactsSidebarOpen = false;
|
|
486
521
|
// Messages displayed in the `ChatView` component.
|
|
487
522
|
#messages: ChatMessage[] = [];
|
|
488
523
|
|
|
@@ -574,6 +609,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
574
609
|
uploadImageInputEnabled: isAiAssistanceMultimodalUploadInputEnabled() &&
|
|
575
610
|
this.#conversation.type === AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING,
|
|
576
611
|
markdownRenderer,
|
|
612
|
+
isArtifactsSidebarOpen: this.#isArtifactsSidebarOpen,
|
|
577
613
|
onTextSubmit: async (
|
|
578
614
|
text: string, imageInput?: Host.AidaClient.Part,
|
|
579
615
|
multimodalInputType?: AiAssistanceModel.AiAgent.MultimodalInputType) => {
|
|
@@ -927,6 +963,11 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
927
963
|
onSettingsClick: () => {
|
|
928
964
|
void UI.ViewManager.ViewManager.instance().showView('chrome-ai');
|
|
929
965
|
},
|
|
966
|
+
onArtifactsSidebarToggle: () => {
|
|
967
|
+
this.#isArtifactsSidebarOpen = !this.#isArtifactsSidebarOpen;
|
|
968
|
+
this.requestUpdate();
|
|
969
|
+
},
|
|
970
|
+
artifactsSidebarVisible: this.#isArtifactsSidebarOpen,
|
|
930
971
|
};
|
|
931
972
|
}
|
|
932
973
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Copyright 2025 The Chromium Authors
|
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
import * as UI from '../../../ui/legacy/legacy.js';
|
|
6
|
+
import * as Lit from '../../../ui/lit/lit.js';
|
|
7
|
+
|
|
8
|
+
import artifactsViewerStyles from './artifactsViewer.css.js';
|
|
9
|
+
|
|
10
|
+
const {html, render} = Lit;
|
|
11
|
+
|
|
12
|
+
export interface ViewInput {
|
|
13
|
+
artifacts: [];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const DEFAULT_VIEW = (
|
|
17
|
+
_input: ViewInput,
|
|
18
|
+
_output: Record<string, unknown>,
|
|
19
|
+
target: HTMLElement,
|
|
20
|
+
): void => {
|
|
21
|
+
// clang-format off
|
|
22
|
+
render(
|
|
23
|
+
html`
|
|
24
|
+
<style>${artifactsViewerStyles}</style>
|
|
25
|
+
<div>
|
|
26
|
+
Artifacts Viewer
|
|
27
|
+
</div>
|
|
28
|
+
`,
|
|
29
|
+
target
|
|
30
|
+
);
|
|
31
|
+
// clang-format on
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type View = typeof DEFAULT_VIEW;
|
|
35
|
+
|
|
36
|
+
export class ArtifactsViewer extends UI.Widget.Widget {
|
|
37
|
+
#view: View;
|
|
38
|
+
constructor(element?: HTMLElement, view = DEFAULT_VIEW) {
|
|
39
|
+
super(element);
|
|
40
|
+
this.#view = view;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
override wasShown(): void {
|
|
44
|
+
super.wasShown();
|
|
45
|
+
void this.requestUpdate();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
override performUpdate(): Promise<void>|void {
|
|
49
|
+
this.#view(
|
|
50
|
+
{
|
|
51
|
+
artifacts: [],
|
|
52
|
+
},
|
|
53
|
+
{},
|
|
54
|
+
this.contentElement,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -265,6 +265,7 @@ export interface Props {
|
|
|
265
265
|
inputPlaceholder: Platform.UIString.LocalizedString;
|
|
266
266
|
disclaimerText: Platform.UIString.LocalizedString;
|
|
267
267
|
isTextInputEmpty: boolean;
|
|
268
|
+
isArtifactsSidebarOpen: boolean;
|
|
268
269
|
uploadImageInputEnabled?: boolean;
|
|
269
270
|
markdownRenderer: MarkdownLitRenderer;
|
|
270
271
|
additionalFloatyContext: UI.Floaty.FloatyContextSelection[];
|
|
@@ -5,9 +5,7 @@
|
|
|
5
5
|
import * as Host from '../../core/host/host.js';
|
|
6
6
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
7
7
|
import type * as Platform from '../../core/platform/platform.js';
|
|
8
|
-
import * as LegacyWrapper from '../../ui/components/legacy_wrapper/legacy_wrapper.js';
|
|
9
8
|
import {createIcon} from '../../ui/kit/kit.js';
|
|
10
|
-
import * as UI from '../../ui/legacy/legacy.js';
|
|
11
9
|
|
|
12
10
|
import {ApplicationPanelTreeElement} from './ApplicationPanelTreeElement.js';
|
|
13
11
|
import * as ApplicationComponents from './components/components.js';
|
|
@@ -23,8 +21,7 @@ const str_ = i18n.i18n.registerUIStrings('panels/application/BounceTrackingMitig
|
|
|
23
21
|
export const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
24
22
|
|
|
25
23
|
export class BounceTrackingMitigationsTreeElement extends ApplicationPanelTreeElement {
|
|
26
|
-
private view?:
|
|
27
|
-
UI.Widget.Widget, ApplicationComponents.BounceTrackingMitigationsView.BounceTrackingMitigationsView>;
|
|
24
|
+
private view?: ApplicationComponents.BounceTrackingMitigationsView.BounceTrackingMitigationsView;
|
|
28
25
|
|
|
29
26
|
constructor(resourcesPanel: ResourcesPanel) {
|
|
30
27
|
super(resourcesPanel, i18nString(UIStrings.bounceTrackingMitigations), false, 'bounce-tracking-mitigations');
|
|
@@ -39,8 +36,7 @@ export class BounceTrackingMitigationsTreeElement extends ApplicationPanelTreeEl
|
|
|
39
36
|
override onselect(selectedByUser?: boolean): boolean {
|
|
40
37
|
super.onselect(selectedByUser);
|
|
41
38
|
if (!this.view) {
|
|
42
|
-
this.view =
|
|
43
|
-
UI.Widget.Widget, new ApplicationComponents.BounceTrackingMitigationsView.BounceTrackingMitigationsView());
|
|
39
|
+
this.view = new ApplicationComponents.BounceTrackingMitigationsView.BounceTrackingMitigationsView();
|
|
44
40
|
}
|
|
45
41
|
this.showView(this.view);
|
|
46
42
|
Host.userMetrics.panelShown('bounce-tracking-mitigations');
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Copyright 2023 The Chromium Authors
|
|
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
|
-
/* eslint-disable @devtools/no-lit-render-outside-of-view */
|
|
5
4
|
|
|
6
5
|
import '../../../ui/components/report_view/report_view.js';
|
|
7
6
|
import '../../../ui/legacy/components/data_grid/data_grid.js';
|
|
@@ -9,7 +8,7 @@ import '../../../ui/legacy/components/data_grid/data_grid.js';
|
|
|
9
8
|
import * as i18n from '../../../core/i18n/i18n.js';
|
|
10
9
|
import * as SDK from '../../../core/sdk/sdk.js';
|
|
11
10
|
import * as Buttons from '../../../ui/components/buttons/buttons.js';
|
|
12
|
-
import * as
|
|
11
|
+
import * as UI from '../../../ui/legacy/legacy.js';
|
|
13
12
|
import * as Lit from '../../../ui/lit/lit.js';
|
|
14
13
|
import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
|
|
15
14
|
|
|
@@ -58,7 +57,8 @@ const UIStrings = {
|
|
|
58
57
|
const str_ = i18n.i18n.registerUIStrings('panels/application/components/BounceTrackingMitigationsView.ts', UIStrings);
|
|
59
58
|
export const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
60
59
|
|
|
61
|
-
const enum ScreenStatusType {
|
|
60
|
+
export const enum ScreenStatusType {
|
|
61
|
+
INITIALIZING = 'Initializing',
|
|
62
62
|
RUNNING = 'Running',
|
|
63
63
|
RESULT = 'Result',
|
|
64
64
|
DISABLED = 'Disabled',
|
|
@@ -68,119 +68,155 @@ export interface BounceTrackingMitigationsViewData {
|
|
|
68
68
|
trackingSites: string[];
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
export
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
connectedCallback(): void {
|
|
79
|
-
void this.#render();
|
|
80
|
-
this.parentElement?.classList.add('overflow-auto');
|
|
81
|
-
}
|
|
71
|
+
export interface ViewInput {
|
|
72
|
+
screenStatus: ScreenStatusType;
|
|
73
|
+
trackingSites: string[];
|
|
74
|
+
seenButtonClick: boolean;
|
|
75
|
+
runMitigations: () => Promise<void>;
|
|
76
|
+
}
|
|
82
77
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
78
|
+
const renderForceRunButton = (input: ViewInput): Lit.TemplateResult => {
|
|
79
|
+
const isMitigationRunning = (input.screenStatus === ScreenStatusType.RUNNING);
|
|
80
|
+
|
|
81
|
+
// clang-format off
|
|
82
|
+
return html`
|
|
83
|
+
<devtools-button
|
|
84
|
+
aria-label=${i18nString(UIStrings.forceRun)}
|
|
85
|
+
.disabled=${isMitigationRunning}
|
|
86
|
+
.spinner=${isMitigationRunning}
|
|
87
|
+
.variant=${Buttons.Button.Variant.PRIMARY}
|
|
88
|
+
@click=${input.runMitigations}
|
|
89
|
+
jslog=${VisualLogging.action('force-run').track({click: true})}>
|
|
90
|
+
${isMitigationRunning ? html`
|
|
91
|
+
${i18nString(UIStrings.runningMitigations)}`:`
|
|
92
|
+
${i18nString(UIStrings.forceRun)}
|
|
93
|
+
`}
|
|
94
|
+
</devtools-button>
|
|
95
|
+
`;
|
|
96
|
+
// clang-format on
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const renderDeletedSitesOrNoSitesMessage = (input: ViewInput): Lit.LitTemplate => {
|
|
100
|
+
if (!input.seenButtonClick) {
|
|
101
|
+
return Lit.nothing;
|
|
93
102
|
}
|
|
94
103
|
|
|
95
|
-
|
|
96
|
-
if (!this.#checkedFeature) {
|
|
97
|
-
await this.#checkFeatureState();
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (this.#screenStatus === ScreenStatusType.DISABLED) {
|
|
101
|
-
// clang-format off
|
|
102
|
-
return html`
|
|
103
|
-
<devtools-report-section>
|
|
104
|
-
${i18nString(UIStrings.featureDisabled)}
|
|
105
|
-
</devtools-report-section>
|
|
106
|
-
`;
|
|
107
|
-
// clang-format on
|
|
108
|
-
}
|
|
109
|
-
|
|
104
|
+
if (input.trackingSites.length === 0) {
|
|
110
105
|
// clang-format off
|
|
111
106
|
return html`
|
|
112
107
|
<devtools-report-section>
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
</devtools-report-divider>
|
|
118
|
-
<devtools-report-section>
|
|
119
|
-
<x-link href="https://privacycg.github.io/nav-tracking-mitigations/#bounce-tracking-mitigations" class="link"
|
|
120
|
-
jslog=${VisualLogging.link('learn-more').track({click: true})}>
|
|
121
|
-
${i18nString(UIStrings.learnMore)}
|
|
122
|
-
</x-link>
|
|
108
|
+
${(input.screenStatus === ScreenStatusType.RUNNING) ? html`
|
|
109
|
+
${i18nString(UIStrings.checkingPotentialTrackers)}`:`
|
|
110
|
+
${i18nString(UIStrings.noPotentialBounceTrackersIdentified)}
|
|
111
|
+
`}
|
|
123
112
|
</devtools-report-section>
|
|
124
113
|
`;
|
|
125
114
|
// clang-format on
|
|
126
115
|
}
|
|
127
116
|
|
|
128
|
-
|
|
129
|
-
|
|
117
|
+
// clang-format off
|
|
118
|
+
return html`
|
|
119
|
+
<devtools-report-section>
|
|
120
|
+
<devtools-data-grid striped inline>
|
|
121
|
+
<table>
|
|
122
|
+
<tr>
|
|
123
|
+
<th id="sites" weight="10" sortable>
|
|
124
|
+
${i18nString(UIStrings.stateDeletedFor)}
|
|
125
|
+
</th>
|
|
126
|
+
</tr>
|
|
127
|
+
${input.trackingSites.map(site => html`
|
|
128
|
+
<tr><td>${site}</td></tr>`)}
|
|
129
|
+
</table>
|
|
130
|
+
</devtools-data-grid>
|
|
131
|
+
</devtools-report-section>
|
|
132
|
+
`;
|
|
133
|
+
// clang-format on
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const renderMainFrameInformation = (input: ViewInput): Lit.LitTemplate => {
|
|
137
|
+
if (input.screenStatus === ScreenStatusType.INITIALIZING) {
|
|
138
|
+
return Lit.nothing;
|
|
139
|
+
}
|
|
130
140
|
|
|
141
|
+
if (input.screenStatus === ScreenStatusType.DISABLED) {
|
|
131
142
|
// clang-format off
|
|
132
143
|
return html`
|
|
133
|
-
<devtools-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
.spinner=${isMitigationRunning}
|
|
137
|
-
.variant=${Buttons.Button.Variant.PRIMARY}
|
|
138
|
-
@click=${this.#runMitigations}
|
|
139
|
-
jslog=${VisualLogging.action('force-run').track({click: true})}>
|
|
140
|
-
${isMitigationRunning ? html`
|
|
141
|
-
${i18nString(UIStrings.runningMitigations)}`:`
|
|
142
|
-
${i18nString(UIStrings.forceRun)}
|
|
143
|
-
`}
|
|
144
|
-
</devtools-button>
|
|
144
|
+
<devtools-report-section>
|
|
145
|
+
${i18nString(UIStrings.featureDisabled)}
|
|
146
|
+
</devtools-report-section>
|
|
145
147
|
`;
|
|
146
148
|
// clang-format on
|
|
147
149
|
}
|
|
148
150
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
// clang-format off
|
|
152
|
+
return html`
|
|
153
|
+
<devtools-report-section>
|
|
154
|
+
${renderForceRunButton(input)}
|
|
155
|
+
</devtools-report-section>
|
|
156
|
+
${renderDeletedSitesOrNoSitesMessage(input)}
|
|
157
|
+
<devtools-report-divider>
|
|
158
|
+
</devtools-report-divider>
|
|
159
|
+
<devtools-report-section>
|
|
160
|
+
<x-link href="https://privacycg.github.io/nav-tracking-mitigations/#bounce-tracking-mitigations" class="link"
|
|
161
|
+
jslog=${VisualLogging.link('learn-more').track({click: true})}>
|
|
162
|
+
${i18nString(UIStrings.learnMore)}
|
|
163
|
+
</x-link>
|
|
164
|
+
</devtools-report-section>
|
|
165
|
+
`;
|
|
166
|
+
// clang-format on
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLElement): void => {
|
|
170
|
+
// clang-format off
|
|
171
|
+
Lit.render(html`
|
|
172
|
+
<style>${bounceTrackingMitigationsViewStyles}</style>
|
|
173
|
+
<style>${UI.inspectorCommonStyles}</style>
|
|
174
|
+
<devtools-report .data=${{reportTitle: i18nString(UIStrings.bounceTrackingMitigationsTitle)}}
|
|
175
|
+
jslog=${VisualLogging.pane('bounce-tracking-mitigations')}>
|
|
176
|
+
${renderMainFrameInformation(input)}
|
|
177
|
+
</devtools-report>
|
|
178
|
+
`, target);
|
|
179
|
+
// clang-format on
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
type ViewFunction = typeof DEFAULT_VIEW;
|
|
183
|
+
|
|
184
|
+
export class BounceTrackingMitigationsView extends UI.Widget.Widget {
|
|
185
|
+
#trackingSites: string[] = [];
|
|
186
|
+
#screenStatus = ScreenStatusType.INITIALIZING;
|
|
187
|
+
#seenButtonClick = false;
|
|
188
|
+
#view: ViewFunction;
|
|
189
|
+
|
|
190
|
+
constructor(element?: HTMLElement, view: ViewFunction = DEFAULT_VIEW) {
|
|
191
|
+
super(element, {useShadowDom: true, classes: ['overflow-auto']});
|
|
153
192
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
// clang-format on
|
|
193
|
+
this.#view = view;
|
|
194
|
+
|
|
195
|
+
const mainTarget = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
|
|
196
|
+
if (!mainTarget) {
|
|
197
|
+
this.#screenStatus = ScreenStatusType.RESULT;
|
|
198
|
+
} else {
|
|
199
|
+
void mainTarget.systemInfo().invoke_getFeatureState({featureState: 'DIPS'}).then(state => {
|
|
200
|
+
this.#screenStatus = state.featureEnabled ? ScreenStatusType.RESULT : ScreenStatusType.DISABLED;
|
|
201
|
+
this.requestUpdate();
|
|
202
|
+
});
|
|
165
203
|
}
|
|
204
|
+
}
|
|
166
205
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
</devtools-report-section>
|
|
182
|
-
`;
|
|
183
|
-
// clang-format on
|
|
206
|
+
override wasShown(): void {
|
|
207
|
+
super.wasShown();
|
|
208
|
+
this.requestUpdate();
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
override performUpdate(): void {
|
|
212
|
+
this.#view(
|
|
213
|
+
{
|
|
214
|
+
screenStatus: this.#screenStatus,
|
|
215
|
+
trackingSites: this.#trackingSites,
|
|
216
|
+
seenButtonClick: this.#seenButtonClick,
|
|
217
|
+
runMitigations: this.#runMitigations.bind(this),
|
|
218
|
+
},
|
|
219
|
+
undefined, this.contentElement);
|
|
184
220
|
}
|
|
185
221
|
|
|
186
222
|
async #runMitigations(): Promise<void> {
|
|
@@ -192,7 +228,7 @@ export class BounceTrackingMitigationsView extends LegacyWrapper.LegacyWrapper.W
|
|
|
192
228
|
this.#seenButtonClick = true;
|
|
193
229
|
this.#screenStatus = ScreenStatusType.RUNNING;
|
|
194
230
|
|
|
195
|
-
|
|
231
|
+
this.requestUpdate();
|
|
196
232
|
|
|
197
233
|
const response = await mainTarget.storageAgent().invoke_runBounceTrackingMitigations();
|
|
198
234
|
this.#trackingSites = [];
|
|
@@ -205,27 +241,6 @@ export class BounceTrackingMitigationsView extends LegacyWrapper.LegacyWrapper.W
|
|
|
205
241
|
|
|
206
242
|
#renderMitigationsResult(): void {
|
|
207
243
|
this.#screenStatus = ScreenStatusType.RESULT;
|
|
208
|
-
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
async #checkFeatureState(): Promise<void> {
|
|
212
|
-
this.#checkedFeature = true;
|
|
213
|
-
|
|
214
|
-
const mainTarget = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
|
|
215
|
-
if (!mainTarget) {
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
if (!(await mainTarget.systemInfo().invoke_getFeatureState({featureState: 'DIPS'})).featureEnabled) {
|
|
220
|
-
this.#screenStatus = ScreenStatusType.DISABLED;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
customElements.define('devtools-bounce-tracking-mitigations-view', BounceTrackingMitigationsView);
|
|
226
|
-
|
|
227
|
-
declare global {
|
|
228
|
-
interface HTMLElementTagNameMap {
|
|
229
|
-
'devtools-bounce-tracking-mitigations-view': BounceTrackingMitigationsView;
|
|
244
|
+
this.requestUpdate();
|
|
230
245
|
}
|
|
231
246
|
}
|
|
@@ -417,7 +417,13 @@ export class PreloadingAttemptView extends UI.Widget.VBox {
|
|
|
417
417
|
this.ruleSetSelector = new PreloadingRuleSetSelector(() => this.render());
|
|
418
418
|
toolbar.appendToolbarItem(this.ruleSetSelector.item());
|
|
419
419
|
|
|
420
|
-
this.preloadingGrid.
|
|
420
|
+
this.preloadingGrid.onSelect = this.onPreloadingGridCellFocused.bind(this);
|
|
421
|
+
|
|
422
|
+
const preloadingGridContainer = document.createElement('div');
|
|
423
|
+
preloadingGridContainer.className = 'preloading-grid-widget-container';
|
|
424
|
+
preloadingGridContainer.style = 'height: 100%';
|
|
425
|
+
this.preloadingGrid.show(preloadingGridContainer, null, true);
|
|
426
|
+
|
|
421
427
|
render(
|
|
422
428
|
html`
|
|
423
429
|
<div class="empty-state">
|
|
@@ -433,7 +439,7 @@ export class PreloadingAttemptView extends UI.Widget.VBox {
|
|
|
433
439
|
</div>
|
|
434
440
|
<devtools-split-view sidebar-position="second">
|
|
435
441
|
<div slot="main" class="overflow-auto" style="height: 100%">
|
|
436
|
-
${
|
|
442
|
+
${preloadingGridContainer}
|
|
437
443
|
</div>
|
|
438
444
|
<div slot="sidebar" class="overflow-auto" style="height: 100%">
|
|
439
445
|
${this.preloadingDetails}
|
|
@@ -500,15 +506,15 @@ export class PreloadingAttemptView extends UI.Widget.VBox {
|
|
|
500
506
|
ruleSets,
|
|
501
507
|
};
|
|
502
508
|
});
|
|
503
|
-
this.preloadingGrid.
|
|
509
|
+
this.preloadingGrid.rows = rows;
|
|
510
|
+
this.preloadingGrid.pageURL = pageURL();
|
|
504
511
|
this.contentElement.classList.toggle('empty', rows.length === 0);
|
|
505
512
|
|
|
506
513
|
this.updatePreloadingDetails();
|
|
507
514
|
}
|
|
508
515
|
|
|
509
|
-
private onPreloadingGridCellFocused(
|
|
510
|
-
|
|
511
|
-
this.focusedPreloadingAttemptId = focusedEvent.detail;
|
|
516
|
+
private onPreloadingGridCellFocused({rowId}: {rowId: string}): void {
|
|
517
|
+
this.focusedPreloadingAttemptId = rowId;
|
|
512
518
|
this.render();
|
|
513
519
|
}
|
|
514
520
|
|