chrome-devtools-frontend 1.0.1661063 → 1.0.1662289
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/evaluate-ai-css-completion/SKILL.md +19 -9
- package/.agents/skills/evaluate-ai-css-completion/scripts/evaluate.js +44 -16
- package/.agents/skills/migrate-chromium-test/SKILL.md +7 -2
- package/.agents/skills/ui-eng-vision-local-lit-renderer/SKILL.md +7 -1
- package/docs/ui_engineering.md +75 -42
- package/front_end/core/common/SettingRegistration.ts +0 -5
- package/front_end/core/platform/ArrayUtilities.ts +10 -0
- package/front_end/foundation/README.md +86 -0
- package/front_end/generated/InspectorBackendCommands.ts +4 -5
- package/front_end/generated/protocol.ts +20 -38
- package/front_end/models/bindings/CompilerScriptMapping.ts +5 -4
- package/front_end/models/bindings/ContentProviderBasedProject.ts +2 -3
- package/front_end/models/bindings/DebuggerLanguagePlugins.ts +4 -3
- package/front_end/models/bindings/DefaultScriptMapping.ts +3 -3
- package/front_end/models/bindings/NetworkProject.ts +10 -1
- package/front_end/models/bindings/ResourceMapping.ts +4 -3
- package/front_end/models/bindings/ResourceScriptMapping.ts +2 -1
- package/front_end/models/bindings/SASSSourceMapping.ts +4 -3
- package/front_end/models/bindings/StylesSourceMapping.ts +3 -3
- package/front_end/models/extensions/RecorderExtensionEndpoint.ts +7 -5
- package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +14 -5
- package/front_end/models/issues_manager/CheckFormsIssuesTrigger.ts +8 -9
- package/front_end/models/issues_manager/RelatedIssue.ts +10 -8
- package/front_end/models/javascript_metadata/NativeFunctions.js +1 -1
- package/front_end/models/logs/RequestResolver.ts +2 -2
- package/front_end/models/persistence/AutomaticFileSystemWorkspaceBinding.ts +0 -5
- package/front_end/models/source_map_scopes/FunctionCodeResolver.ts +1 -1
- package/front_end/models/trace/handlers/FramesHandler.ts +4 -7
- package/front_end/models/trace/handlers/ModelHandlers.ts +0 -1
- package/front_end/models/trace/handlers/RendererHandler.ts +2 -15
- package/front_end/models/trace/handlers/Threads.ts +4 -11
- package/front_end/models/trace/insights/DOMSize.ts +1 -1
- package/front_end/models/workspace/WorkspaceImpl.ts +1 -10
- package/front_end/panels/application/ApplicationPanelSidebar.ts +0 -44
- package/front_end/panels/application/CookieItemsView.ts +1 -1
- package/front_end/panels/application/FrameDetailsView.ts +1 -1
- package/front_end/panels/application/ServiceWorkersView.ts +494 -411
- package/front_end/panels/application/application.ts +0 -6
- package/front_end/panels/application/components/components.ts +0 -2
- package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +1 -1
- package/front_end/panels/application/serviceWorkersView.css +40 -4
- package/front_end/panels/browser_debugger/XHRBreakpointsSidebarPane.ts +147 -123
- package/front_end/panels/common/ExtensionServer.ts +3 -3
- package/front_end/panels/console/ConsoleView.ts +1 -1
- package/front_end/panels/emulation/DeviceModeView.ts +139 -70
- package/front_end/panels/issues/AffectedResourcesView.ts +1 -1
- package/front_end/panels/lighthouse/LighthouseProtocolService.ts +53 -12
- package/front_end/panels/network/RequestPayloadView.ts +77 -39
- package/front_end/panels/network/components/ResponseHeaderSection.ts +5 -3
- package/front_end/panels/profiler/HeapSnapshotView.ts +2 -2
- package/front_end/panels/recorder/RecorderController.ts +213 -49
- package/front_end/panels/recorder/RecorderPanel.ts +1 -1
- package/front_end/panels/sources/SourcesNavigator.ts +3 -2
- package/front_end/panels/sources/SourcesView.ts +0 -17
- package/front_end/panels/sources/UISourceCodeFrame.ts +42 -0
- package/front_end/panels/sources/sources.ts +0 -2
- package/front_end/panels/timeline/CompatibilityTracksAppender.ts +0 -17
- package/front_end/panels/timeline/ThreadAppender.ts +0 -106
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/components/report_view/ReportView.ts +11 -5
- package/front_end/ui/components/report_view/report.css +4 -1
- package/front_end/ui/legacy/TextPrompt.ts +49 -1
- package/front_end/ui/legacy/UIUtils.ts +11 -1
- package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +2 -2
- package/front_end/ui/legacy/textPrompt.css +10 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
- package/package.json +1 -1
- package/front_end/models/trace/handlers/AuctionWorkletsHandler.ts +0 -183
- package/front_end/panels/application/InterestGroupStorageModel.ts +0 -81
- package/front_end/panels/application/InterestGroupStorageView.ts +0 -151
- package/front_end/panels/application/InterestGroupTreeElement.ts +0 -65
- package/front_end/panels/application/components/InterestGroupAccessGrid.ts +0 -135
- package/front_end/panels/application/components/interestGroupAccessGrid.css +0 -27
- package/front_end/panels/application/interestGroupStorageView.css +0 -9
- package/front_end/panels/sources/InplaceFormatterEditorAction.ts +0 -149
|
@@ -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,149 +0,0 @@
|
|
|
1
|
-
// Copyright 2014 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 Common from '../../core/common/common.js';
|
|
7
|
-
import * as i18n from '../../core/i18n/i18n.js';
|
|
8
|
-
import * as Formatter from '../../models/formatter/formatter.js';
|
|
9
|
-
import * as Persistence from '../../models/persistence/persistence.js';
|
|
10
|
-
import * as TextUtils from '../../models/text_utils/text_utils.js';
|
|
11
|
-
import * as Workspace from '../../models/workspace/workspace.js';
|
|
12
|
-
import * as UI from '../../ui/legacy/legacy.js';
|
|
13
|
-
|
|
14
|
-
import {
|
|
15
|
-
type EditorAction,
|
|
16
|
-
type EditorClosedEvent,
|
|
17
|
-
Events,
|
|
18
|
-
registerEditorAction,
|
|
19
|
-
type SourcesView,
|
|
20
|
-
} from './SourcesView.js';
|
|
21
|
-
import type {UISourceCodeFrame} from './UISourceCodeFrame.js';
|
|
22
|
-
|
|
23
|
-
const UIStrings = {
|
|
24
|
-
/**
|
|
25
|
-
* @description Title of the format button in the Sources panel
|
|
26
|
-
* @example {file name} PH1
|
|
27
|
-
*/
|
|
28
|
-
formatS: 'Format {PH1}',
|
|
29
|
-
/**
|
|
30
|
-
* @description Tooltip text that appears when hovering over the largeicon pretty print button in the Inplace Formatter Editor Action of the Sources panel
|
|
31
|
-
*/
|
|
32
|
-
format: 'Format',
|
|
33
|
-
} as const;
|
|
34
|
-
const str_ = i18n.i18n.registerUIStrings('panels/sources/InplaceFormatterEditorAction.ts', UIStrings);
|
|
35
|
-
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
36
|
-
|
|
37
|
-
let inplaceFormatterEditorActionInstance: InplaceFormatterEditorAction;
|
|
38
|
-
|
|
39
|
-
export class InplaceFormatterEditorAction implements EditorAction {
|
|
40
|
-
private button!: UI.Toolbar.ToolbarButton;
|
|
41
|
-
private sourcesView!: SourcesView;
|
|
42
|
-
private uiSourceCodeTitleChangedEvent: Common.EventTarget.EventDescriptor|null = null;
|
|
43
|
-
static instance(opts: {
|
|
44
|
-
forceNew: boolean|null,
|
|
45
|
-
} = {forceNew: null}): InplaceFormatterEditorAction {
|
|
46
|
-
const {forceNew} = opts;
|
|
47
|
-
if (!inplaceFormatterEditorActionInstance || forceNew) {
|
|
48
|
-
inplaceFormatterEditorActionInstance = new InplaceFormatterEditorAction();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return inplaceFormatterEditorActionInstance;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
private editorSelected(event: Common.EventTarget.EventTargetEvent<Workspace.UISourceCode.UISourceCode>): void {
|
|
55
|
-
const uiSourceCode = event.data;
|
|
56
|
-
this.updateButton(uiSourceCode);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
private editorClosed(event: Common.EventTarget.EventTargetEvent<EditorClosedEvent>): void {
|
|
60
|
-
const {wasSelected} = event.data;
|
|
61
|
-
if (wasSelected) {
|
|
62
|
-
this.updateButton(null);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
private updateButton(uiSourceCode: Workspace.UISourceCode.UISourceCode|null): void {
|
|
67
|
-
if (this.uiSourceCodeTitleChangedEvent) {
|
|
68
|
-
Common.EventTarget.removeEventListeners([this.uiSourceCodeTitleChangedEvent]);
|
|
69
|
-
}
|
|
70
|
-
this.uiSourceCodeTitleChangedEvent = uiSourceCode ?
|
|
71
|
-
uiSourceCode.addEventListener(
|
|
72
|
-
Workspace.UISourceCode.Events.TitleChanged, event => this.updateButton(event.data), this) :
|
|
73
|
-
null;
|
|
74
|
-
const isFormattable = this.isFormattable(uiSourceCode);
|
|
75
|
-
this.button.element.classList.toggle('hidden', !isFormattable);
|
|
76
|
-
if (uiSourceCode && isFormattable) {
|
|
77
|
-
this.button.setTitle(i18nString(UIStrings.formatS, {PH1: uiSourceCode.name()}));
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
getOrCreateButton(sourcesView: SourcesView): UI.Toolbar.ToolbarButton {
|
|
82
|
-
if (this.button) {
|
|
83
|
-
return this.button;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
this.sourcesView = sourcesView;
|
|
87
|
-
this.sourcesView.addEventListener(Events.EDITOR_SELECTED, this.editorSelected.bind(this));
|
|
88
|
-
this.sourcesView.addEventListener(Events.EDITOR_CLOSED, this.editorClosed.bind(this));
|
|
89
|
-
|
|
90
|
-
this.button = new UI.Toolbar.ToolbarButton(i18nString(UIStrings.format), 'brackets');
|
|
91
|
-
this.button.addEventListener(UI.Toolbar.ToolbarButton.Events.CLICK, this.formatSourceInPlace, this);
|
|
92
|
-
this.updateButton(sourcesView.currentUISourceCode());
|
|
93
|
-
|
|
94
|
-
return this.button;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
private isFormattable(uiSourceCode: Workspace.UISourceCode.UISourceCode|null): boolean {
|
|
98
|
-
if (!uiSourceCode) {
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
// Only show Format button for editable files
|
|
102
|
-
if (!Persistence.Persistence.PersistenceImpl.instance().hasEditableContent(uiSourceCode)) {
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
// Only show Format button for JavaScript files. For other file types (JSON, CSS),
|
|
106
|
-
// the pretty-print toggle in the status bar should be used instead, which provides
|
|
107
|
-
// reversible formatting (fixes issue 378870233).
|
|
108
|
-
const mimeType = Common.ResourceType.ResourceType.simplifyContentType(uiSourceCode.mimeType());
|
|
109
|
-
return Common.ResourceType.ResourceType.isJavaScriptMimeType(mimeType);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
private formatSourceInPlace(): void {
|
|
113
|
-
const sourceFrame = this.sourcesView.currentSourceFrame();
|
|
114
|
-
if (!sourceFrame) {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
const uiSourceCode = sourceFrame.uiSourceCode();
|
|
118
|
-
if (!this.isFormattable(uiSourceCode)) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (uiSourceCode.isDirty()) {
|
|
123
|
-
void this.contentLoaded(uiSourceCode, sourceFrame, uiSourceCode.workingCopy());
|
|
124
|
-
} else {
|
|
125
|
-
void uiSourceCode.requestContentData()
|
|
126
|
-
.then(contentDataOrError => TextUtils.ContentData.ContentData.textOr(contentDataOrError, ''))
|
|
127
|
-
.then(content => {
|
|
128
|
-
void this.contentLoaded(uiSourceCode, sourceFrame, content);
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
private async contentLoaded(
|
|
134
|
-
uiSourceCode: Workspace.UISourceCode.UISourceCode, sourceFrame: UISourceCodeFrame,
|
|
135
|
-
content: string): Promise<void> {
|
|
136
|
-
const {formattedContent, formattedMapping} = await Formatter.ScriptFormatter.format(
|
|
137
|
-
Common.Settings.Settings.instance(), uiSourceCode.contentType(), sourceFrame.contentType, content);
|
|
138
|
-
if (uiSourceCode.workingCopy() === formattedContent) {
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
const selection = sourceFrame.textEditor.toLineColumn(sourceFrame.textEditor.state.selection.main.head);
|
|
142
|
-
const [lineNumber, columnNumber] =
|
|
143
|
-
formattedMapping.originalToFormatted(selection.lineNumber, selection.columnNumber);
|
|
144
|
-
uiSourceCode.setWorkingCopy(formattedContent);
|
|
145
|
-
this.sourcesView.showSourceLocation(uiSourceCode, {lineNumber, columnNumber});
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
registerEditorAction(InplaceFormatterEditorAction.instance);
|