chrome-devtools-frontend 1.0.1661063 → 1.0.1662965

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/.agents/skills/devtools-unicode-escaping/SKILL.md +64 -0
  2. package/.agents/skills/evaluate-ai-css-completion/SKILL.md +19 -9
  3. package/.agents/skills/evaluate-ai-css-completion/scripts/evaluate.js +44 -16
  4. package/.agents/skills/migrate-chromium-test/SKILL.md +32 -2
  5. package/.agents/skills/ui-eng-vision-local-lit-renderer/SKILL.md +7 -1
  6. package/docs/ui_engineering.md +75 -42
  7. package/front_end/core/common/SettingRegistration.ts +0 -10
  8. package/front_end/core/common/Settings.ts +69 -3
  9. package/front_end/core/platform/ArrayUtilities.ts +10 -0
  10. package/front_end/core/platform/StringUtilities.ts +38 -6
  11. package/front_end/core/sdk/ServiceWorkerCacheModel.ts +0 -10
  12. package/front_end/core/sdk/StorageBucketsModel.ts +0 -10
  13. package/front_end/core/sdk/sdk-meta.ts +0 -1
  14. package/front_end/entrypoints/inspector_main/OutermostTargetSelector.ts +0 -13
  15. package/front_end/entrypoints/inspector_main/RenderingOptions.ts +8 -3
  16. package/front_end/entrypoints/inspector_main/inspector_main-meta.ts +3 -3
  17. package/front_end/entrypoints/main/MainImpl.ts +7 -2
  18. package/front_end/foundation/README.md +86 -0
  19. package/front_end/foundation/Universe.ts +16 -0
  20. package/front_end/generated/InspectorBackendCommands.ts +6 -19
  21. package/front_end/generated/protocol-mapping.d.ts +0 -53
  22. package/front_end/generated/protocol-proxy-api.d.ts +0 -46
  23. package/front_end/generated/protocol.ts +20 -186
  24. package/front_end/models/ai_assistance/AiAgent2.ts +3 -3
  25. package/front_end/models/ai_assistance/AiConversation.ts +21 -10
  26. package/front_end/models/ai_assistance/AiHistoryStorage.ts +21 -10
  27. package/front_end/models/ai_assistance/ChangeManager.ts +2 -2
  28. package/front_end/models/ai_assistance/ExtensionScope.ts +6 -2
  29. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +1 -1
  30. package/front_end/models/ai_assistance/agents/AiAgent.ts +8 -1
  31. package/front_end/models/ai_assistance/agents/StylingAgent.ts +1 -1
  32. package/front_end/models/badges/UserBadges.ts +31 -17
  33. package/front_end/models/bindings/CompilerScriptMapping.ts +5 -4
  34. package/front_end/models/bindings/ContentProviderBasedProject.ts +2 -3
  35. package/front_end/models/bindings/DebuggerLanguagePlugins.ts +4 -3
  36. package/front_end/models/bindings/DefaultScriptMapping.ts +3 -3
  37. package/front_end/models/bindings/NetworkProject.ts +22 -1
  38. package/front_end/models/bindings/ResourceMapping.ts +4 -3
  39. package/front_end/models/bindings/ResourceScriptMapping.ts +2 -1
  40. package/front_end/models/bindings/SASSSourceMapping.ts +4 -3
  41. package/front_end/models/bindings/StylesSourceMapping.ts +3 -3
  42. package/front_end/models/emulation/DeviceModeModel.ts +67 -5
  43. package/front_end/models/extensions/RecorderExtensionEndpoint.ts +7 -5
  44. package/front_end/models/extensions/RecorderPluginManager.ts +10 -6
  45. package/front_end/models/har/Log.snapshot.txt +193 -0
  46. package/front_end/models/har/Log.ts +3 -2
  47. package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +14 -5
  48. package/front_end/models/issues_manager/CheckFormsIssuesTrigger.ts +8 -9
  49. package/front_end/models/issues_manager/RelatedIssue.ts +10 -8
  50. package/front_end/models/javascript_metadata/NativeFunctions.js +1 -1
  51. package/front_end/models/logs/RequestResolver.ts +2 -2
  52. package/front_end/models/persistence/AutomaticFileSystemWorkspaceBinding.ts +0 -5
  53. package/front_end/models/source_map_scopes/FunctionCodeResolver.ts +8 -6
  54. package/front_end/models/source_map_scopes/NamesResolver.ts +36 -30
  55. package/front_end/models/stack_trace/StackTrace.ts +17 -0
  56. package/front_end/models/trace/handlers/FramesHandler.ts +4 -7
  57. package/front_end/models/trace/handlers/ModelHandlers.ts +0 -1
  58. package/front_end/models/trace/handlers/RendererHandler.ts +2 -15
  59. package/front_end/models/trace/handlers/Threads.ts +4 -11
  60. package/front_end/models/trace/insights/DOMSize.ts +1 -1
  61. package/front_end/models/workspace/WorkspaceImpl.ts +1 -10
  62. package/front_end/panels/application/ApplicationPanelSidebar.ts +0 -44
  63. package/front_end/panels/application/CookieItemsView.ts +1 -1
  64. package/front_end/panels/application/FrameDetailsView.ts +1 -1
  65. package/front_end/panels/application/IndexedDBModel.ts +0 -10
  66. package/front_end/panels/application/IndexedDBViews.ts +240 -164
  67. package/front_end/panels/application/ServiceWorkersView.ts +494 -411
  68. package/front_end/panels/application/SharedStorageModel.ts +0 -10
  69. package/front_end/panels/application/application.ts +0 -6
  70. package/front_end/panels/application/components/AdsView.ts +23 -0
  71. package/front_end/panels/application/components/SharedStorageAccessGrid.ts +1 -1
  72. package/front_end/panels/application/components/adsView.css +21 -1
  73. package/front_end/panels/application/components/components.ts +0 -2
  74. package/front_end/panels/application/indexedDBViews.css +1 -1
  75. package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +1 -1
  76. package/front_end/panels/application/serviceWorkersView.css +40 -4
  77. package/front_end/panels/browser_debugger/XHRBreakpointsSidebarPane.ts +147 -123
  78. package/front_end/panels/common/ExtensionServer.ts +3 -3
  79. package/front_end/panels/console/ConsoleView.ts +1 -1
  80. package/front_end/panels/emulation/DeviceModeView.ts +139 -70
  81. package/front_end/panels/issues/AffectedResourcesView.ts +1 -1
  82. package/front_end/panels/lighthouse/LighthouseProtocolService.ts +53 -12
  83. package/front_end/panels/network/NetworkDataGridNode.ts +43 -1
  84. package/front_end/panels/network/RequestInitiatorView.ts +24 -2
  85. package/front_end/panels/network/RequestPayloadView.ts +77 -39
  86. package/front_end/panels/network/components/ResponseHeaderSection.ts +5 -3
  87. package/front_end/panels/network/networkLogView.css +5 -0
  88. package/front_end/panels/network/requestInitiatorViewTree.css +5 -0
  89. package/front_end/panels/profiler/HeapProfileView.ts +198 -79
  90. package/front_end/panels/profiler/HeapSnapshotView.ts +2 -2
  91. package/front_end/panels/recorder/README.md +1 -2
  92. package/front_end/panels/recorder/RecorderPanel.ts +1749 -17
  93. package/front_end/panels/recorder/recorder.ts +0 -2
  94. package/front_end/panels/settings/AISettingsTab.ts +13 -0
  95. package/front_end/panels/sources/SourcesNavigator.ts +3 -2
  96. package/front_end/panels/sources/SourcesView.ts +0 -17
  97. package/front_end/panels/sources/UISourceCodeFrame.ts +42 -0
  98. package/front_end/panels/sources/sources.ts +0 -2
  99. package/front_end/panels/timeline/CompatibilityTracksAppender.ts +0 -17
  100. package/front_end/panels/timeline/ThreadAppender.ts +0 -106
  101. package/front_end/third_party/chromium/README.chromium +1 -1
  102. package/front_end/ui/components/report_view/ReportView.ts +11 -5
  103. package/front_end/ui/components/report_view/report.css +4 -1
  104. package/front_end/ui/components/spinners/Spinner.ts +29 -32
  105. package/front_end/ui/components/spinners/spinner.css +32 -84
  106. package/front_end/ui/legacy/TextPrompt.ts +49 -1
  107. package/front_end/ui/legacy/Treeoutline.ts +14 -6
  108. package/front_end/ui/legacy/UIUtils.ts +36 -11
  109. package/front_end/ui/legacy/Widget.ts +17 -10
  110. package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +2 -2
  111. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +36 -7
  112. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +63 -68
  113. package/front_end/ui/legacy/components/object_ui/RemoteObjectPreviewFormatter.ts +1 -1
  114. package/front_end/ui/legacy/components/object_ui/objectValue.css +2 -1
  115. package/front_end/ui/legacy/inspectorCommon.css +4 -4
  116. package/front_end/ui/legacy/textPrompt.css +10 -0
  117. package/front_end/ui/lit/lit.ts +1 -0
  118. package/front_end/ui/lit/render.ts +44 -10
  119. package/front_end/ui/lit/strip-whitespace.ts +23 -2
  120. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
  121. package/package.json +1 -1
  122. package/front_end/models/trace/handlers/AuctionWorkletsHandler.ts +0 -183
  123. package/front_end/panels/application/InterestGroupStorageModel.ts +0 -81
  124. package/front_end/panels/application/InterestGroupStorageView.ts +0 -151
  125. package/front_end/panels/application/InterestGroupTreeElement.ts +0 -65
  126. package/front_end/panels/application/components/InterestGroupAccessGrid.ts +0 -135
  127. package/front_end/panels/application/components/interestGroupAccessGrid.css +0 -27
  128. package/front_end/panels/application/interestGroupStorageView.css +0 -9
  129. package/front_end/panels/recorder/RecorderController.ts +0 -1595
  130. package/front_end/panels/sources/InplaceFormatterEditorAction.ts +0 -149
  131. /package/front_end/panels/recorder/{recorderController.css → recorderPanel.css} +0 -0
@@ -1,183 +0,0 @@
1
- // Copyright 2023 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 Helpers from '../helpers/helpers.js';
6
- import * as Types from '../types/types.js';
7
-
8
- /**
9
- * There are two metadata events that we care about.
10
- * => AuctionWorkletRunningInProcess tells us which process the Auction Worklet
11
- * has taken to run in.
12
- * => AuctionWorkletDoneWithProcess tells us when the worklet is done with that
13
- * process. This is less useful - but in the future we might want to surface
14
- * this information so we still parse and return the event.
15
- *
16
- * It is important to note that the top level PID on these events is NOT the
17
- * PID that the worklet is running on; instead we have to look at its
18
- * args.data.pid property, which is the PID of the process that it is running
19
- * on.
20
- *
21
- * For any given RunningInProcess event, we would typically expect to see a
22
- * DoneWithProcess event, however this is not guaranteed, especially as users
23
- * can record any chunk of time in DevTools.
24
- *
25
- * Similarly, it is also possible to see a DoneWithProcess event without a
26
- * RunningInProcess event, if the user started recording after the auction
27
- * worklets started. Therefore we are happy to create
28
- * SyntheticAuctionWorklets as long as we see just one of these events.
29
- *
30
- * If we do get two events and need to pair them, we can use the
31
- * args.data.target property, which is a string ID shared by both
32
- * events.
33
- */
34
- let runningInProcessEvents = new Map<Types.Events.ProcessID, Types.Events.AuctionWorkletRunningInProcess>();
35
- let doneWithProcessEvents = new Map<Types.Events.ProcessID, Types.Events.AuctionWorkletDoneWithProcess>();
36
-
37
- // Keyed by the PID defined in `args.data.pid` on AuctionWorklet trace events..
38
- let createdSyntheticEvents = new Map<Types.Events.ProcessID, Types.Events.SyntheticAuctionWorklet>();
39
-
40
- // Each AuctonWorklet takes over a process and has 2 threads (that we care
41
- // about and want to show as tracks):
42
- // 1. A CrUtilityMain thread which is known as the "control process".
43
- // 2. A AuctionV8HelperThread which is the actual auction worklet and will be
44
- // either a "Seller" or a "Bidder"
45
- // To detect these we look for the metadata thread_name events. We key these by
46
- // PID so that we can easily look them up later without having to loop through.
47
- let utilityThreads = new Map<Types.Events.ProcessID, Types.Events.ThreadName>();
48
- let v8HelperThreads = new Map<Types.Events.ProcessID, Types.Events.ThreadName>();
49
-
50
- export function reset(): void {
51
- runningInProcessEvents = new Map();
52
- doneWithProcessEvents = new Map();
53
- createdSyntheticEvents = new Map();
54
- utilityThreads = new Map();
55
- v8HelperThreads = new Map();
56
- }
57
-
58
- export function handleEvent(event: Types.Events.Event): void {
59
- if (Types.Events.isAuctionWorkletRunningInProcess(event)) {
60
- runningInProcessEvents.set(event.args.data.pid, event);
61
- return;
62
- }
63
-
64
- if (Types.Events.isAuctionWorkletDoneWithProcess(event)) {
65
- doneWithProcessEvents.set(event.args.data.pid, event);
66
- return;
67
- }
68
-
69
- if (Types.Events.isThreadName(event)) {
70
- if (event.args.name === 'auction_worklet.CrUtilityMain') {
71
- utilityThreads.set(event.pid, event);
72
- return;
73
- }
74
- if (event.args.name === 'AuctionV8HelperThread') {
75
- v8HelperThreads.set(event.pid, event);
76
- }
77
- }
78
- }
79
-
80
- function workletType(input: string): Types.Events.AuctionWorkletType {
81
- switch (input) {
82
- case 'seller':
83
- return Types.Events.AuctionWorkletType.SELLER;
84
- case 'bidder':
85
- return Types.Events.AuctionWorkletType.BIDDER;
86
- default:
87
- return Types.Events.AuctionWorkletType.UNKNOWN;
88
- }
89
- }
90
-
91
- /**
92
- * We cannot make the full event without knowing the type of event, but we can
93
- * create everything other than the `args` field, as those are identical
94
- * regardless of the type of event.
95
- */
96
- function makeSyntheticEventBase(
97
- event: Types.Events.AuctionWorkletDoneWithProcess|
98
- Types.Events.AuctionWorkletRunningInProcess): Omit<Types.Events.SyntheticAuctionWorklet, 'args'> {
99
- return Helpers.SyntheticEvents.SyntheticEventsManager
100
- .registerSyntheticEvent<Omit<Types.Events.SyntheticAuctionWorklet, 'args'>>({
101
- rawSourceEvent: event,
102
- name: 'SyntheticAuctionWorklet',
103
- s: Types.Events.Scope.THREAD,
104
- cat: event.cat,
105
- tid: event.tid,
106
- ts: event.ts,
107
- ph: Types.Events.Phase.INSTANT,
108
- pid: event.args.data.pid,
109
- host: event.args.data.host,
110
- target: event.args.data.target,
111
- type: workletType(event.args.data.type),
112
- });
113
- }
114
-
115
- export async function finalize(): Promise<void> {
116
- // Loop through the utility threads we found to create the worklet events. We
117
- // expect each worklet to have a utility thread, so we can use them as the
118
- // root of our list of worklets.
119
- for (const [pid, utilityThreadNameEvent] of utilityThreads) {
120
- const v8HelperEvent = v8HelperThreads.get(pid);
121
- if (!v8HelperEvent) {
122
- // Bad trace data - AuctionWorklets are expected to always have both threads.
123
- continue;
124
- }
125
-
126
- const runningEvent = runningInProcessEvents.get(pid);
127
- const doneWithEvent = doneWithProcessEvents.get(pid);
128
-
129
- // We can create a worklet from either the runningEvent or doneWithEvent -
130
- // we do not need both. We cannot express that to TypeScript with an early
131
- // return here, so instead we set the event initially to null, and then
132
- // create it from either the running event or the doneWith event. If it is
133
- // still null after this, that means neither event was found, and we drop
134
- // the worklet as we do not have enough information to create the synthetic
135
- // event.
136
-
137
- let syntheticEvent: Types.Events.SyntheticAuctionWorklet|null = null;
138
-
139
- if (runningEvent) {
140
- syntheticEvent = {
141
- ...makeSyntheticEventBase(runningEvent),
142
- args: {
143
- data: {
144
- runningInProcessEvent: runningEvent,
145
- utilityThread: utilityThreadNameEvent,
146
- v8HelperThread: v8HelperEvent,
147
- },
148
- },
149
- };
150
- if (doneWithEvent) {
151
- syntheticEvent.args.data.doneWithProcessEvent = doneWithEvent;
152
- }
153
- } else if (doneWithEvent) {
154
- syntheticEvent = {
155
- ...makeSyntheticEventBase(doneWithEvent),
156
- args: {
157
- data: {
158
- doneWithProcessEvent: doneWithEvent,
159
- utilityThread: utilityThreadNameEvent,
160
- v8HelperThread: v8HelperEvent,
161
- },
162
- },
163
- };
164
- if (runningEvent) {
165
- syntheticEvent.args.data.runningInProcessEvent = runningEvent;
166
- }
167
- }
168
- if (syntheticEvent === null) {
169
- continue;
170
- }
171
- createdSyntheticEvents.set(pid, syntheticEvent);
172
- }
173
- }
174
-
175
- export interface AuctionWorkletsData {
176
- worklets: Map<Types.Events.ProcessID, Types.Events.SyntheticAuctionWorklet>;
177
- }
178
-
179
- export function data(): AuctionWorkletsData {
180
- return {
181
- worklets: createdSyntheticEvents,
182
- };
183
- }
@@ -1,81 +0,0 @@
1
- // Copyright 2021 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 SDK from '../../core/sdk/sdk.js';
6
- import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js';
7
- import type * as Protocol from '../../generated/protocol.js';
8
-
9
- export class InterestGroupStorageModel extends SDK.SDKModel.SDKModel<EventTypes> implements
10
- ProtocolProxyApi.StorageDispatcher {
11
- private readonly storageAgent: ProtocolProxyApi.StorageApi;
12
- private enabled?: boolean;
13
-
14
- constructor(target: SDK.Target.Target) {
15
- super(target);
16
- target.registerStorageDispatcher(this);
17
- this.storageAgent = target.storageAgent();
18
- this.enabled = false;
19
- }
20
-
21
- enable(): void {
22
- if (this.enabled) {
23
- return;
24
- }
25
- void this.storageAgent.invoke_setInterestGroupTracking({enable: true});
26
- }
27
-
28
- disable(): void {
29
- if (!this.enabled) {
30
- return;
31
- }
32
- void this.storageAgent.invoke_setInterestGroupTracking({enable: false});
33
- }
34
-
35
- interestGroupAccessed(event: Protocol.Storage.InterestGroupAccessedEvent): void {
36
- this.dispatchEventToListeners(Events.INTEREST_GROUP_ACCESS, event);
37
- }
38
-
39
- indexedDBListUpdated(_event: Protocol.Storage.IndexedDBListUpdatedEvent): void {
40
- }
41
-
42
- indexedDBContentUpdated(_event: Protocol.Storage.IndexedDBContentUpdatedEvent): void {
43
- }
44
-
45
- interestGroupAuctionEventOccurred(_event: Protocol.Storage.InterestGroupAuctionEventOccurredEvent): void {
46
- }
47
-
48
- interestGroupAuctionNetworkRequestCreated(_event: Protocol.Storage.InterestGroupAuctionNetworkRequestCreatedEvent):
49
- void {
50
- }
51
-
52
- cacheStorageListUpdated(_event: Protocol.Storage.CacheStorageListUpdatedEvent): void {
53
- }
54
-
55
- cacheStorageContentUpdated(_event: Protocol.Storage.CacheStorageContentUpdatedEvent): void {
56
- }
57
-
58
- sharedStorageAccessed(_event: Protocol.Storage.SharedStorageAccessedEvent): void {
59
- }
60
-
61
- sharedStorageWorkletOperationExecutionFinished(
62
- _event: Protocol.Storage.SharedStorageWorkletOperationExecutionFinishedEvent): void {
63
- }
64
-
65
- storageBucketCreatedOrUpdated(_event: Protocol.Storage.StorageBucketCreatedOrUpdatedEvent): void {
66
- }
67
-
68
- storageBucketDeleted(_event: Protocol.Storage.StorageBucketDeletedEvent): void {
69
- }
70
- }
71
-
72
- SDK.SDKModel.SDKModel.register(
73
- InterestGroupStorageModel, {capabilities: SDK.Target.Capability.STORAGE, autostart: false});
74
-
75
- export const enum Events {
76
- INTEREST_GROUP_ACCESS = 'InterestGroupAccess',
77
- }
78
-
79
- export interface EventTypes {
80
- [Events.INTEREST_GROUP_ACCESS]: Protocol.Storage.InterestGroupAccessedEvent;
81
- }
@@ -1,151 +0,0 @@
1
- // Copyright 2021 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
- /* eslint-disable @devtools/no-imperative-dom-api */
5
-
6
- import * as i18n from '../../core/i18n/i18n.js';
7
- import * as Protocol from '../../generated/protocol.js';
8
- import * as SourceFrame from '../../ui/legacy/components/source_frame/source_frame.js';
9
- import * as UI from '../../ui/legacy/legacy.js';
10
- import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
11
-
12
- import * as ApplicationComponents from './components/components.js';
13
- import interestGroupStorageViewStyles from './interestGroupStorageView.css.js';
14
-
15
- const UIStrings = {
16
- /**
17
- * @description Placeholder text shown when nothing has been selected for display
18
- *details.
19
- * An interest group is an ad targeting group stored on the browser that can
20
- * be used to show a certain set of advertisements in the future as the
21
- * outcome of a FLEDGE auction.
22
- */
23
- noValueSelected: 'No interest group selected',
24
- /**
25
- * @description Placeholder text instructing the user how to display interest group
26
- *details.
27
- * An interest group is an ad targeting group stored on the browser that can
28
- * be used to show a certain set of advertisements in the future as the
29
- * outcome of a FLEDGE auction.
30
- */
31
- clickToDisplayBody: 'Select any interest group event to display the group\'s current state',
32
- /**
33
- * @description Placeholder text telling the user no details are available for
34
- *the selected interest group.
35
- */
36
- noDataAvailable: 'No details available',
37
- /**
38
- * @description Placeholder text explaining to the user a potential reason for not having details on
39
- * the interest groups.
40
- * An interest group is an ad targeting group stored on the browser that can
41
- * be used to show a certain set of advertisements in the future as the
42
- * outcome of a FLEDGE auction.
43
- */
44
- noDataDescription: 'The browser may have left the group.',
45
- } as const;
46
- const str_ = i18n.i18n.registerUIStrings('panels/application/InterestGroupStorageView.ts', UIStrings);
47
- const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
48
-
49
- interface InterestGroupDetailsGetter {
50
- getInterestGroupDetails: (owner: string, name: string) => Promise<object|null>;
51
- }
52
-
53
- function eventEquals(
54
- a: Protocol.Storage.InterestGroupAccessedEvent, b: Protocol.Storage.InterestGroupAccessedEvent): boolean {
55
- return (a.accessTime === b.accessTime && a.type === b.type && a.ownerOrigin === b.ownerOrigin && a.name === b.name);
56
- }
57
-
58
- export class InterestGroupStorageView extends UI.SplitWidget.SplitWidget {
59
- private readonly interestGroupGrid = new ApplicationComponents.InterestGroupAccessGrid.InterestGroupAccessGrid();
60
- private events: Protocol.Storage.InterestGroupAccessedEvent[] = [];
61
- private detailsGetter: InterestGroupDetailsGetter;
62
- private noDataView: UI.Widget.VBox;
63
- private noDisplayView: UI.Widget.VBox;
64
-
65
- constructor(detailsGetter: InterestGroupDetailsGetter) {
66
- super(/* isVertical */ false, /* secondIsSidebar: */ true);
67
- this.element.setAttribute('jslog', `${VisualLogging.pane('interest-groups')}`);
68
- this.detailsGetter = detailsGetter;
69
-
70
- const topPanel = new UI.Widget.VBox();
71
- this.noDisplayView =
72
- new UI.EmptyWidget.EmptyWidget(i18nString(UIStrings.noValueSelected), i18nString(UIStrings.clickToDisplayBody));
73
- this.noDataView =
74
- new UI.EmptyWidget.EmptyWidget(i18nString(UIStrings.noDataAvailable), i18nString(UIStrings.noDataDescription));
75
-
76
- topPanel.setMinimumSize(0, 120);
77
- this.setMainWidget(topPanel);
78
- this.noDisplayView.setMinimumSize(0, 80);
79
- this.setSidebarWidget(this.noDisplayView);
80
- this.noDataView.setMinimumSize(0, 80);
81
- this.noDisplayView.contentElement.setAttribute('jslog', `${VisualLogging.pane('details').track({resize: true})}`);
82
- this.noDataView.contentElement.setAttribute('jslog', `${VisualLogging.pane('details').track({resize: true})}`);
83
- this.hideSidebar();
84
-
85
- topPanel.contentElement.appendChild(this.interestGroupGrid);
86
- this.interestGroupGrid.addEventListener('select', this.onFocus.bind(this));
87
- }
88
-
89
- override wasShown(): void {
90
- super.wasShown();
91
- const mainWidget = this.mainWidget();
92
- if (mainWidget) {
93
- mainWidget.registerRequiredCSS(interestGroupStorageViewStyles);
94
- }
95
- }
96
-
97
- addEvent(event: Protocol.Storage.InterestGroupAccessedEvent): void {
98
- if (this.showMode() !== UI.SplitWidget.ShowMode.BOTH) {
99
- this.showBoth();
100
- }
101
- // Only add if not already present.
102
- const foundEvent = this.events.find(t => eventEquals(t, event));
103
- if (!foundEvent) {
104
- this.events.push(event);
105
- this.interestGroupGrid.data = this.events;
106
- }
107
- }
108
-
109
- clearEvents(): void {
110
- this.events = [];
111
- this.interestGroupGrid.data = this.events;
112
- this.setSidebarWidget(this.noDisplayView);
113
- this.sidebarUpdatedForTesting();
114
- }
115
-
116
- private async onFocus(event: Event): Promise<void> {
117
- const focusedEvent = event as CustomEvent<Protocol.Storage.InterestGroupAccessedEvent>;
118
- const {ownerOrigin, name, type: eventType} = focusedEvent.detail;
119
-
120
- let details = null;
121
- // Details of additional bids can't be looked up like regular bids,
122
- // they are ephemeral to the auction.
123
- if (eventType !== Protocol.Storage.InterestGroupAccessType.AdditionalBid &&
124
- eventType !== Protocol.Storage.InterestGroupAccessType.AdditionalBidWin &&
125
- eventType !== Protocol.Storage.InterestGroupAccessType.TopLevelAdditionalBid) {
126
- details = await this.detailsGetter.getInterestGroupDetails(ownerOrigin, name);
127
- }
128
- if (details) {
129
- const jsonView = await SourceFrame.JSONView.JSONView.createView(JSON.stringify(details));
130
- jsonView?.setMinimumSize(0, 40);
131
- if (jsonView) {
132
- jsonView.contentElement.setAttribute('jslog', `${VisualLogging.pane('details').track({resize: true})}`);
133
- this.setSidebarWidget(jsonView);
134
- }
135
- } else {
136
- this.setSidebarWidget(this.noDataView);
137
- }
138
- this.sidebarUpdatedForTesting();
139
- }
140
-
141
- getEventsForTesting(): Protocol.Storage.InterestGroupAccessedEvent[] {
142
- return this.events;
143
- }
144
-
145
- getInterestGroupGridForTesting(): ApplicationComponents.InterestGroupAccessGrid.InterestGroupAccessGrid {
146
- return this.interestGroupGrid;
147
- }
148
-
149
- sidebarUpdatedForTesting(): void {
150
- }
151
- }
@@ -1,65 +0,0 @@
1
- // Copyright 2022 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 i18n from '../../core/i18n/i18n.js';
6
- import type * as Platform from '../../core/platform/platform.js';
7
- import * as SDK from '../../core/sdk/sdk.js';
8
- import type * as Protocol from '../../generated/protocol.js';
9
- import {createIcon} from '../../ui/kit/kit.js';
10
- import * as UI from '../../ui/legacy/legacy.js';
11
-
12
- import {ApplicationPanelTreeElement} from './ApplicationPanelTreeElement.js';
13
- import {InterestGroupStorageView} from './InterestGroupStorageView.js';
14
- import type {ResourcesPanel} from './ResourcesPanel.js';
15
-
16
- const UIStrings = {
17
- /**
18
- * @description Label for an item in the Application Panel Sidebar of the Application panel
19
- * An interest group is an ad targeting group stored on the browser that can
20
- * be used to show a certain set of advertisements in the future as the
21
- * outcome of a FLEDGE auction. (https://developer.chrome.com/blog/fledge-api/)
22
- */
23
- interestGroups: 'Interest groups',
24
- } as const;
25
- const str_ = i18n.i18n.registerUIStrings('panels/application/InterestGroupTreeElement.ts', UIStrings);
26
- export const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
27
-
28
- export class InterestGroupTreeElement extends ApplicationPanelTreeElement {
29
- private view: InterestGroupStorageView;
30
-
31
- constructor(storagePanel: ResourcesPanel) {
32
- super(storagePanel, i18nString(UIStrings.interestGroups), false, 'interest-groups');
33
- const interestGroupIcon = createIcon('database');
34
- this.setLeadingIcons([interestGroupIcon]);
35
- this.view = new InterestGroupStorageView(this);
36
- }
37
-
38
- override get itemURL(): Platform.DevToolsPath.UrlString {
39
- return 'interest-groups://' as Platform.DevToolsPath.UrlString;
40
- }
41
-
42
- async getInterestGroupDetails(owner: string, name: string): Promise<object|null> {
43
- const mainTarget = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
44
- if (!mainTarget) {
45
- return null;
46
- }
47
- const response = await mainTarget.storageAgent().invoke_getInterestGroupDetails({ownerOrigin: owner, name});
48
- return response.details;
49
- }
50
-
51
- override onselect(selectedByUser?: boolean): boolean {
52
- super.onselect(selectedByUser);
53
- this.showView(this.view);
54
- UI.UIUserMetrics.UIUserMetrics.instance().panelShown('interest-groups');
55
- return false;
56
- }
57
-
58
- addEvent(event: Protocol.Storage.InterestGroupAccessedEvent): void {
59
- this.view.addEvent(event);
60
- }
61
-
62
- clearEvents(): void {
63
- this.view.clearEvents();
64
- }
65
- }
@@ -1,135 +0,0 @@
1
- // Copyright 2022 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
- /* eslint-disable @devtools/no-lit-render-outside-of-view */
5
-
6
- import '../../../ui/legacy/components/data_grid/data_grid.js';
7
-
8
- import * as i18n from '../../../core/i18n/i18n.js';
9
- import type * as Protocol from '../../../generated/protocol.js';
10
- import * as UI from '../../../ui/legacy/legacy.js';
11
- import * as Lit from '../../../ui/lit/lit.js';
12
-
13
- import interestGroupAccessGridStyles from './interestGroupAccessGrid.css.js';
14
-
15
- const {html} = Lit;
16
-
17
- const UIStrings = {
18
- /**
19
- * @description Hover text for an info icon in the Interest Group Event panel
20
- * An interest group is an ad targeting group stored on the browser that can
21
- * be used to show a certain set of advertisements in the future as the
22
- * outcome of a FLEDGE auction.
23
- */
24
- allInterestGroupStorageEvents: 'All interest group storage events.',
25
- /**
26
- * @description Text in InterestGroupStorage Items View of the Application panel
27
- * Date and time of an Interest Group storage event in a locale-
28
- * dependent format.
29
- */
30
- eventTime: 'Event Time',
31
- /**
32
- * @description Text in InterestGroupStorage Items View of the Application panel
33
- * Type of interest group event such as 'join', 'bid', 'win', or 'leave'.
34
- */
35
- eventType: 'Access Type',
36
- /**
37
- * @description Text in InterestGroupStorage Items View of the Application panel
38
- * Owner of the interest group. The origin that controls the
39
- * content of information associated with the interest group such as which
40
- * ads get displayed.
41
- */
42
- groupOwner: 'Owner',
43
- /**
44
- * @description Text in InterestGroupStorage Items View of the Application panel
45
- * Name of the interest group. The name is unique per-owner and identifies the
46
- * interest group.
47
- */
48
- groupName: 'Name',
49
- /**
50
- * @description Text shown when no interest groups are detected.
51
- * An interest group is an ad targeting group stored on the browser that can
52
- * be used to show a certain set of advertisements in the future as the
53
- * outcome of a FLEDGE auction.
54
- */
55
- noEvents: 'No interest group events detected',
56
- /**
57
- * @description Text shown when no interest groups are detected and explains what this page is about.
58
- * An interest group is an ad targeting group stored on the browser that can
59
- * be used to show a certain set of advertisements in the future as the
60
- * outcome of a FLEDGE auction.
61
- */
62
- interestGroupDescription: 'On this page you can inspect and analyze interest groups',
63
- } as const;
64
- const str_ = i18n.i18n.registerUIStrings('panels/application/components/InterestGroupAccessGrid.ts', UIStrings);
65
- export const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
66
-
67
- export class InterestGroupAccessGrid extends HTMLElement {
68
- readonly #shadow = this.attachShadow({mode: 'open'});
69
- #datastores: Protocol.Storage.InterestGroupAccessedEvent[] = [];
70
-
71
- connectedCallback(): void {
72
- this.#render();
73
- }
74
-
75
- // eslint-disable-next-line @devtools/set-data-type-reference
76
- set data(data: Protocol.Storage.InterestGroupAccessedEvent[]) {
77
- this.#datastores = data;
78
- this.#render();
79
- }
80
-
81
- #render(): void {
82
- // clang-format off
83
- Lit.render(html`
84
- <style>${interestGroupAccessGridStyles}</style>
85
- <style>${UI.inspectorCommonStyles}</style>
86
- ${this.#datastores.length === 0 ?
87
- html`
88
- <div class="empty-state">
89
- <span class="empty-state-header">${i18nString(UIStrings.noEvents)}</span>
90
- <span class="empty-state-description">${i18nString(UIStrings.interestGroupDescription)}</span>
91
- </div>`:
92
- html`
93
- <div>
94
- <span class="heading">Interest Groups</span>
95
- <devtools-icon class="info-icon medium" name="info"
96
- title=${i18nString(UIStrings.allInterestGroupStorageEvents)}>
97
- </devtools-icon>
98
- ${this.#renderGrid()}
99
- </div>`}
100
- `, this.#shadow, {host: this});
101
- // clang-format on
102
- }
103
-
104
- #renderGrid(): Lit.TemplateResult {
105
- // clang-format off
106
- return html`
107
- <devtools-data-grid striped inline>
108
- <table>
109
- <tr>
110
- <th id="event-time" sortable weight="10">${i18nString(UIStrings.eventTime)}</td>
111
- <th id="event-type" sortable weight="5">${i18nString(UIStrings.eventType)}</td>
112
- <th id="event-group-owner" sortable weight="10">${i18nString(UIStrings.groupOwner)}</td>
113
- <th id="event-group-name" sortable weight="10">${i18nString(UIStrings.groupName)}</td>
114
- </tr>
115
- ${this.#datastores.map(event => html`
116
- <tr @select=${() => this.dispatchEvent(new CustomEvent('select', {detail: event}))}>
117
- <td>${new Date(1e3 * event.accessTime).toLocaleString()}</td>
118
- <td>${event.type}</td>
119
- <td>${event.ownerOrigin}</td>
120
- <td>${event.name}</td>
121
- </tr>
122
- `)}
123
- </table>
124
- </devtools-data-grid>`;
125
- // clang-format on
126
- }
127
- }
128
-
129
- customElements.define('devtools-interest-group-access-grid', InterestGroupAccessGrid);
130
-
131
- declare global {
132
- interface HTMLElementTagNameMap {
133
- 'devtools-interest-group-access-grid': InterestGroupAccessGrid;
134
- }
135
- }
@@ -1,27 +0,0 @@
1
- /*
2
- * Copyright 2021 The Chromium Authors
3
- * Use of this source code is governed by a BSD-style license that can be
4
- * found in the LICENSE file.
5
- */
6
- :host {
7
- display: flex;
8
- padding: 20px;
9
- height: 100%;
10
- }
11
-
12
- .heading {
13
- font-size: 15px;
14
- }
15
-
16
- devtools-data-grid {
17
- margin-top: 20px;
18
- }
19
-
20
- .info-icon {
21
- vertical-align: text-bottom;
22
- height: 14px;
23
- }
24
-
25
- .no-events-message {
26
- margin-top: 20px;
27
- }
@@ -1,9 +0,0 @@
1
- /*
2
- * Copyright 2021 The Chromium Authors
3
- * Use of this source code is governed by a BSD-style license that can be
4
- * found in the LICENSE file.
5
- */
6
-
7
- devtools-interest-group-access-grid {
8
- overflow: auto;
9
- }