chrome-devtools-frontend 1.0.1521746 → 1.0.1522145
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/front_end/core/host/GdpClient.ts +116 -66
- package/front_end/core/root/Runtime.ts +1 -0
- package/front_end/entrypoints/inspector_main/InspectorMain.ts +82 -32
- package/front_end/entrypoints/inspector_main/inspector_main-meta.ts +1 -1
- package/front_end/entrypoints/main/MainImpl.ts +7 -1
- package/front_end/generated/InspectorBackendCommands.js +3 -2
- package/front_end/generated/protocol-mapping.d.ts +9 -0
- package/front_end/generated/protocol-proxy-api.d.ts +8 -0
- package/front_end/generated/protocol.ts +12 -0
- package/front_end/models/ai_assistance/agents/NetworkAgent.ts +10 -6
- package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +42 -4
- package/front_end/models/badges/UserBadges.ts +14 -16
- package/front_end/panels/ai_assistance/components/UserActionRow.ts +1 -2
- package/front_end/panels/application/IndexedDBViews.ts +1 -0
- package/front_end/panels/application/ReportingApiTreeElement.ts +1 -2
- package/front_end/panels/application/ReportingApiView.ts +18 -20
- package/front_end/panels/application/ServiceWorkerCacheViews.ts +3 -0
- package/front_end/panels/application/components/EndpointsGrid.ts +51 -59
- package/front_end/panels/application/components/ReportsGrid.ts +86 -107
- package/front_end/panels/application/components/StorageMetadataView.ts +30 -4
- package/front_end/panels/application/components/endpointsGrid.css +30 -0
- package/front_end/panels/application/components/reportsGrid.css +34 -0
- package/front_end/panels/application/components/storageMetadataView.css +9 -0
- package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +19 -27
- package/front_end/panels/common/BadgeNotification.ts +10 -3
- package/front_end/panels/network/NetworkPanel.ts +1 -1
- package/front_end/panels/search/SearchResultsPane.ts +14 -13
- package/front_end/panels/search/SearchView.ts +3 -20
- package/front_end/panels/settings/components/SyncSection.ts +8 -6
- package/front_end/panels/sources/SearchSourcesView.ts +1 -1
- package/front_end/panels/whats_new/ReleaseNoteText.ts +15 -11
- package/front_end/panels/whats_new/resources/WNDT.md +9 -6
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/diff/README.chromium +0 -1
- package/front_end/ui/legacy/Treeoutline.ts +6 -9
- package/front_end/ui/legacy/UIUtils.ts +4 -17
- package/front_end/ui/legacy/Widget.ts +0 -5
- package/front_end/ui/legacy/XElement.ts +0 -33
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +3 -3
- package/front_end/ui/legacy/components/perf_ui/FilmStripView.ts +38 -21
- package/front_end/ui/legacy/components/perf_ui/filmStripView.css +29 -0
- package/front_end/ui/legacy/components/source_frame/XMLView.ts +3 -2
- package/front_end/ui/legacy/legacy.ts +0 -2
- package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
- package/package.json +1 -1
- package/front_end/panels/application/components/reportingApiGrid.css +0 -31
- package/front_end/ui/legacy/XWidget.ts +0 -133
@@ -1,23 +1,17 @@
|
|
1
1
|
// Copyright 2021 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 rulesdir/no-lit-render-outside-of-view */
|
5
4
|
|
6
5
|
import '../../../ui/legacy/components/data_grid/data_grid.js';
|
7
|
-
import '../../../ui/components/icon_button/icon_button.js';
|
8
|
-
import '../../../ui/legacy/legacy.js';
|
9
6
|
|
10
7
|
import * as i18n from '../../../core/i18n/i18n.js';
|
11
8
|
import * as Root from '../../../core/root/root.js';
|
12
9
|
import type * as Protocol from '../../../generated/protocol.js';
|
13
|
-
// inspectorCommonStyles is imported for the empty state styling that is used for the start view
|
14
|
-
// eslint-disable-next-line rulesdir/es-modules-import
|
15
|
-
import inspectorCommonStyles from '../../../ui/legacy/inspectorCommon.css.js';
|
16
10
|
import * as UI from '../../../ui/legacy/legacy.js';
|
17
11
|
import * as Lit from '../../../ui/lit/lit.js';
|
18
12
|
import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
|
19
13
|
|
20
|
-
import
|
14
|
+
import reportsGridStyles from './reportsGrid.css.js';
|
21
15
|
|
22
16
|
const UIStrings = {
|
23
17
|
/**
|
@@ -48,7 +42,7 @@ const UIStrings = {
|
|
48
42
|
* @description Column header for a table displaying Reporting API reports.
|
49
43
|
*The column contains the timestamp of when a report was generated.
|
50
44
|
*/
|
51
|
-
generatedAt: 'Generated at'
|
45
|
+
generatedAt: 'Generated at',
|
52
46
|
} as const;
|
53
47
|
const str_ = i18n.i18n.registerUIStrings('panels/application/components/ReportsGrid.ts', UIStrings);
|
54
48
|
export const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
@@ -57,115 +51,100 @@ const {render, html} = Lit;
|
|
57
51
|
|
58
52
|
const REPORTING_API_EXPLANATION_URL = 'https://developer.chrome.com/docs/capabilities/web-apis/reporting-api';
|
59
53
|
|
60
|
-
export class ReportsGridStatusHeader extends HTMLElement {
|
61
|
-
readonly #shadow = this.attachShadow({mode: 'open'});
|
62
|
-
|
63
|
-
connectedCallback(): void {
|
64
|
-
this.#render();
|
65
|
-
}
|
66
|
-
|
67
|
-
#render(): void {
|
68
|
-
// Disabled until https://crbug.com/1079231 is fixed.
|
69
|
-
// clang-format off
|
70
|
-
render(html`
|
71
|
-
<style>${reportingApiGridStyles}</style>
|
72
|
-
<span class="status-header">${i18nString(UIStrings.status)}</span>
|
73
|
-
<x-link href="https://web.dev/reporting-api/#report-status"
|
74
|
-
jslog=${VisualLogging.link('report-status').track({click: true})}>
|
75
|
-
<devtools-icon class="inline-icon medium" name="help" style="color: var(--icon-link);"></devtools-icon>
|
76
|
-
</x-link>
|
77
|
-
`, this.#shadow, {host: this});
|
78
|
-
// clang-format on
|
79
|
-
}
|
80
|
-
}
|
81
|
-
|
82
54
|
export interface ReportsGridData {
|
83
55
|
reports: Protocol.Network.ReportingApiReport[];
|
84
56
|
}
|
85
57
|
|
86
|
-
export
|
87
|
-
|
88
|
-
|
89
|
-
|
58
|
+
export interface ViewInput {
|
59
|
+
reports: Protocol.Network.ReportingApiReport[];
|
60
|
+
protocolMonitorExperimentEnabled: boolean;
|
61
|
+
onSelect: (e: CustomEvent<HTMLElement|null>) => void;
|
62
|
+
}
|
90
63
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
64
|
+
export const DEFAULT_VIEW = (input: ViewInput, output: undefined, target: HTMLElement): void => {
|
65
|
+
// clang-format off
|
66
|
+
render(html`
|
67
|
+
<style>${reportsGridStyles}</style>
|
68
|
+
<style>${UI.inspectorCommonStyles}</style>
|
69
|
+
<div class="reporting-container" jslog=${VisualLogging.section('reports')}>
|
70
|
+
<div class="reporting-header">${i18n.i18n.lockedString('Reports')}</div>
|
71
|
+
${input.reports.length > 0 ? html`
|
72
|
+
<devtools-data-grid striped @select=${input.onSelect}>
|
73
|
+
<table>
|
74
|
+
<tr>
|
75
|
+
${input.protocolMonitorExperimentEnabled ? html`
|
76
|
+
<th id="id" weight="30">${i18n.i18n.lockedString('ID')}</th>
|
77
|
+
` : ''}
|
78
|
+
<th id="url" weight="30">${i18n.i18n.lockedString('URL')}</th>
|
79
|
+
<th id="type" weight="20">${i18n.i18n.lockedString('Type')}</th>
|
80
|
+
<th id="status" weight="20">
|
81
|
+
<style>${reportsGridStyles}</style>
|
82
|
+
<span class="status-header">${i18nString(UIStrings.status)}</span>
|
83
|
+
<x-link href="https://web.dev/reporting-api/#report-status"
|
84
|
+
jslog=${VisualLogging.link('report-status').track({click: true})}>
|
85
|
+
<devtools-icon class="inline-icon medium" name="help" style="color: var(--icon-link);"
|
86
|
+
></devtools-icon>
|
87
|
+
</x-link>
|
88
|
+
</th>
|
89
|
+
<th id="destination" weight="20">${i18nString(UIStrings.destination)}</th>
|
90
|
+
<th id="timestamp" weight="20">${i18nString(UIStrings.generatedAt)}</th>
|
91
|
+
<th id="body" weight="20">${i18n.i18n.lockedString('Body')}</th>
|
92
|
+
</tr>
|
93
|
+
${input.reports.map(report => html`
|
94
|
+
<tr data-id=${report.id}>
|
95
|
+
${input.protocolMonitorExperimentEnabled ? html`<td>${report.id}</td>` : ''}
|
96
|
+
<td>${report.initiatorUrl}</td>
|
97
|
+
<td>${report.type}</td>
|
98
|
+
<td>${report.status}</td>
|
99
|
+
<td>${report.destination}</td>
|
100
|
+
<td>${new Date(report.timestamp * 1000).toLocaleString()}</td>
|
101
|
+
<td>${JSON.stringify(report.body)}</td>
|
102
|
+
</tr>
|
103
|
+
`)}
|
104
|
+
</table>
|
105
|
+
</devtools-data-grid>
|
106
|
+
` : html`
|
107
|
+
<div class="empty-state">
|
108
|
+
<span class="empty-state-header">${i18nString(UIStrings.noReportsToDisplay)}</span>
|
109
|
+
<div class="empty-state-description">
|
110
|
+
<span>${i18nString(UIStrings.reportingApiDescription)}</span>
|
111
|
+
${UI.XLink.XLink.create(REPORTING_API_EXPLANATION_URL, i18nString(UIStrings.learnMore), undefined,
|
112
|
+
undefined, 'learn-more')}
|
113
|
+
</div>
|
114
|
+
</div>
|
115
|
+
`}
|
116
|
+
</div>
|
117
|
+
`, target);
|
118
|
+
// clang-format on
|
119
|
+
};
|
95
120
|
|
96
|
-
|
97
|
-
this.#reports = data.reports;
|
98
|
-
this.#render();
|
99
|
-
}
|
121
|
+
type View = typeof DEFAULT_VIEW;
|
100
122
|
|
101
|
-
|
102
|
-
|
103
|
-
|
123
|
+
export class ReportsGrid extends UI.Widget.Widget {
|
124
|
+
reports: Protocol.Network.ReportingApiReport[] = [];
|
125
|
+
#protocolMonitorExperimentEnabled = false;
|
126
|
+
#view: View;
|
127
|
+
onReportSelected: (id: string) => void = () => {};
|
104
128
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
<style>${inspectorCommonStyles}</style>
|
111
|
-
<div class="reporting-container" jslog=${VisualLogging.section('reports')}>
|
112
|
-
<div class="reporting-header">${i18n.i18n.lockedString('Reports')}</div>
|
113
|
-
${this.#reports.length > 0 ? html`
|
114
|
-
<devtools-data-grid striped @select=${this.#onSelect}>
|
115
|
-
<table>
|
116
|
-
<tr>
|
117
|
-
${this.#protocolMonitorExperimentEnabled ? html`
|
118
|
-
<th id="id" weight="30">${i18n.i18n.lockedString('ID')}</th>
|
119
|
-
` : ''}
|
120
|
-
<th id="url" weight="30">${i18n.i18n.lockedString('URL')}</th>
|
121
|
-
<th id="type" weight="20">${i18n.i18n.lockedString('Type')}</th>
|
122
|
-
<th id="status" weight="20">
|
123
|
-
<devtools-resources-reports-grid-status-header></devtools-resources-reports-grid-status-header>
|
124
|
-
</th>
|
125
|
-
<th id="destination" weight="20">${i18nString(UIStrings.destination)}</th>
|
126
|
-
<th id="timestamp" weight="20">${i18nString(UIStrings.generatedAt)}</th>
|
127
|
-
<th id="body" weight="20">${i18n.i18n.lockedString('Body')}</th>
|
128
|
-
</tr>
|
129
|
-
${this.#reports.map(report => html`
|
130
|
-
<tr data-id=${report.id}>
|
131
|
-
${this.#protocolMonitorExperimentEnabled ? html`<td>${report.id}</td>` : ''}
|
132
|
-
<td>${report.initiatorUrl}</td>
|
133
|
-
<td>${report.type}</td>
|
134
|
-
<td>${report.status}</td>
|
135
|
-
<td>${report.destination}</td>
|
136
|
-
<td>${new Date(report.timestamp * 1000).toLocaleString()}</td>
|
137
|
-
<td>${JSON.stringify(report.body)}</td>
|
138
|
-
</tr>
|
139
|
-
`)}
|
140
|
-
</table>
|
141
|
-
</devtools-data-grid>
|
142
|
-
` : html`
|
143
|
-
<div class="empty-state">
|
144
|
-
<span class="empty-state-header">${i18nString(UIStrings.noReportsToDisplay)}</span>
|
145
|
-
<div class="empty-state-description">
|
146
|
-
<span>${i18nString(UIStrings.reportingApiDescription)}</span>
|
147
|
-
${UI.XLink.XLink.create(REPORTING_API_EXPLANATION_URL, i18nString(UIStrings.learnMore), undefined, undefined, 'learn-more')}
|
148
|
-
</div>
|
149
|
-
</div>
|
150
|
-
`}
|
151
|
-
</div>
|
152
|
-
`, this.#shadow, {host: this});
|
153
|
-
// clang-format on
|
129
|
+
constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
|
130
|
+
super(element);
|
131
|
+
this.#view = view;
|
132
|
+
this.#protocolMonitorExperimentEnabled = Root.Runtime.experiments.isEnabled('protocol-monitor');
|
133
|
+
this.requestUpdate();
|
154
134
|
}
|
155
135
|
|
156
|
-
#onSelect(e: CustomEvent<HTMLElement|null>): void {
|
157
|
-
if (e.detail) {
|
158
|
-
this.
|
136
|
+
#onSelect = (e: CustomEvent<HTMLElement|null>): void => {
|
137
|
+
if (e.detail?.dataset.id) {
|
138
|
+
this.onReportSelected(e.detail.dataset.id);
|
159
139
|
}
|
160
|
-
}
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
'devtools-resources-reports-grid': ReportsGrid;
|
140
|
+
};
|
141
|
+
|
142
|
+
override performUpdate(): void {
|
143
|
+
const viewInput = {
|
144
|
+
reports: this.reports,
|
145
|
+
protocolMonitorExperimentEnabled: this.#protocolMonitorExperimentEnabled,
|
146
|
+
onSelect: this.#onSelect,
|
147
|
+
};
|
148
|
+
this.#view(viewInput, undefined, this.contentElement);
|
170
149
|
}
|
171
150
|
}
|
@@ -14,6 +14,8 @@ import * as RenderCoordinator from '../../../ui/components/render_coordinator/re
|
|
14
14
|
import * as UI from '../../../ui/legacy/legacy.js';
|
15
15
|
import * as Lit from '../../../ui/lit/lit.js';
|
16
16
|
|
17
|
+
import storageMetadataViewStyle from './storageMetadataView.css.js';
|
18
|
+
|
17
19
|
const {html} = Lit;
|
18
20
|
|
19
21
|
const UIStrings = {
|
@@ -21,7 +23,7 @@ const UIStrings = {
|
|
21
23
|
* @description The origin of a URL (https://web.dev/same-site-same-origin/#origin).
|
22
24
|
*(for a lot of languages this does not need to be translated, please translate only where necessary)
|
23
25
|
*/
|
24
|
-
origin: '
|
26
|
+
origin: 'Frame origin',
|
25
27
|
/**
|
26
28
|
* @description Site (https://web.dev/same-site-same-origin/#site) for the URL the user sees in the omnibox.
|
27
29
|
*/
|
@@ -118,6 +120,7 @@ export class StorageMetadataView extends LegacyWrapper.LegacyWrapper.WrappableCo
|
|
118
120
|
#storageBucketsModel?: SDK.StorageBucketsModel.StorageBucketsModel;
|
119
121
|
#storageKey: SDK.StorageKeyManager.StorageKey|null = null;
|
120
122
|
#storageBucket: Protocol.Storage.StorageBucketInfo|null = null;
|
123
|
+
#showOnlyBucket = true;
|
121
124
|
|
122
125
|
setStorageKey(storageKey: string): void {
|
123
126
|
this.#storageKey = SDK.StorageKeyManager.parseStorageKey(storageKey);
|
@@ -129,6 +132,10 @@ export class StorageMetadataView extends LegacyWrapper.LegacyWrapper.WrappableCo
|
|
129
132
|
this.setStorageKey(storageBucket.bucket.storageKey);
|
130
133
|
}
|
131
134
|
|
135
|
+
setShowOnlyBucket(show: boolean): void {
|
136
|
+
this.#showOnlyBucket = show;
|
137
|
+
}
|
138
|
+
|
132
139
|
enableStorageBucketControls(model: SDK.StorageBucketsModel.StorageBucketsModel): void {
|
133
140
|
this.#storageBucketsModel = model;
|
134
141
|
if (this.#storageKey) {
|
@@ -141,6 +148,9 @@ export class StorageMetadataView extends LegacyWrapper.LegacyWrapper.WrappableCo
|
|
141
148
|
// Disabled until https://crbug.com/1079231 is fixed.
|
142
149
|
// clang-format off
|
143
150
|
Lit.render(html`
|
151
|
+
<style>
|
152
|
+
${storageMetadataViewStyle}
|
153
|
+
</style>
|
144
154
|
<devtools-report .data=${{reportTitle: this.getTitle() ?? i18nString(UIStrings.loading)}}>
|
145
155
|
${await this.renderReportContent()}
|
146
156
|
</devtools-report>`, this.#shadow, {host: this});
|
@@ -181,11 +191,16 @@ export class StorageMetadataView extends LegacyWrapper.LegacyWrapper.WrappableCo
|
|
181
191
|
topLevelSiteIsOpaque ? i18nString(UIStrings.yesBecauseTopLevelIsOpaque) :
|
182
192
|
(topLevelSite && origin !== topLevelSite) ? i18nString(UIStrings.yesBecauseOriginNotInTopLevelSite) :
|
183
193
|
null;
|
194
|
+
|
195
|
+
const isIframeOrEmbedded = topLevelSite && origin !== topLevelSite;
|
196
|
+
|
184
197
|
// Disabled until https://crbug.com/1079231 is fixed.
|
185
198
|
// clang-format off
|
186
199
|
return html`
|
187
|
-
${
|
188
|
-
|
200
|
+
${(isIframeOrEmbedded) ?
|
201
|
+
html`${this.key(i18nString(UIStrings.origin))}
|
202
|
+
${this.value(html`<div class="text-ellipsis" title=${origin}>${origin}</div>`)}`
|
203
|
+
: Lit.nothing}
|
189
204
|
${(topLevelSite || topLevelSiteIsOpaque) ? this.key(i18nString(UIStrings.topLevelSite)) : Lit.nothing}
|
190
205
|
${topLevelSite ? this.value(topLevelSite) : Lit.nothing}
|
191
206
|
${topLevelSiteIsOpaque ? this.value(i18nString(UIStrings.opaque)) : Lit.nothing}
|
@@ -205,11 +220,22 @@ export class StorageMetadataView extends LegacyWrapper.LegacyWrapper.WrappableCo
|
|
205
220
|
throw new Error('Should not call #renderStorageBucketInfo if #bucket is null.');
|
206
221
|
}
|
207
222
|
const {bucket: {name}, persistent, durability, quota} = this.#storageBucket;
|
223
|
+
const isDefault = !name;
|
208
224
|
|
225
|
+
if (!this.#showOnlyBucket) {
|
226
|
+
if (isDefault) {
|
227
|
+
return html`
|
228
|
+
${this.key(i18nString(UIStrings.bucketName))}
|
229
|
+
${this.value(html`<span class="default-bucket">default</span>`)}`;
|
230
|
+
}
|
231
|
+
return html`
|
232
|
+
${this.key(i18nString(UIStrings.bucketName))}
|
233
|
+
${this.value(name)}`;
|
234
|
+
}
|
209
235
|
// clang-format off
|
210
236
|
return html`
|
211
237
|
${this.key(i18nString(UIStrings.bucketName))}
|
212
|
-
${this.value(name ||
|
238
|
+
${this.value(name || html`<span class="default-bucket">default</span>`)}
|
213
239
|
${this.key(i18nString(UIStrings.persistent))}
|
214
240
|
${this.value(persistent ? i18nString(UIStrings.yes) : i18nString(UIStrings.no))}
|
215
241
|
${this.key(i18nString(UIStrings.durability))}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2025 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
|
+
@scope to (devtools-widget > *) {
|
8
|
+
:scope {
|
9
|
+
overflow: auto;
|
10
|
+
height: 100%;
|
11
|
+
}
|
12
|
+
|
13
|
+
.endpoints-container {
|
14
|
+
height: 100%;
|
15
|
+
display: flex;
|
16
|
+
flex-direction: column;
|
17
|
+
width: 100%;
|
18
|
+
}
|
19
|
+
|
20
|
+
.endpoints-header {
|
21
|
+
font-size: 15px;
|
22
|
+
background-color: var(--sys-color-surface2);
|
23
|
+
padding: 1px 4px;
|
24
|
+
flex-shrink: 0;
|
25
|
+
}
|
26
|
+
|
27
|
+
devtools-data-grid {
|
28
|
+
flex: auto;
|
29
|
+
}
|
30
|
+
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2025 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
|
+
@scope to (devtools-widget > *) {
|
8
|
+
:scope {
|
9
|
+
overflow: auto;
|
10
|
+
height: 100%;
|
11
|
+
}
|
12
|
+
|
13
|
+
.reporting-container {
|
14
|
+
height: 100%;
|
15
|
+
display: flex;
|
16
|
+
flex-direction: column;
|
17
|
+
width: 100%;
|
18
|
+
}
|
19
|
+
|
20
|
+
.reporting-header {
|
21
|
+
font-size: 15px;
|
22
|
+
background-color: var(--sys-color-surface2);
|
23
|
+
padding: 1px 4px;
|
24
|
+
flex-shrink: 0;
|
25
|
+
}
|
26
|
+
|
27
|
+
devtools-data-grid {
|
28
|
+
flex: auto;
|
29
|
+
}
|
30
|
+
|
31
|
+
.inline-icon {
|
32
|
+
vertical-align: text-bottom;
|
33
|
+
}
|
34
|
+
}
|
@@ -183,29 +183,23 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
|
|
183
183
|
'source-code': true,
|
184
184
|
'breakpoint-hit': input.highlightedItem === breakpoint,
|
185
185
|
});
|
186
|
-
const
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
if (expanded) {
|
204
|
-
output.userExpandedCategories.add(category);
|
205
|
-
} else {
|
206
|
-
output.userExpandedCategories.delete(category);
|
207
|
-
}
|
208
|
-
};
|
186
|
+
const onExpand =
|
187
|
+
(category: SDK.CategorizedBreakpoint.Category, {detail: {expanded}}: UI.TreeOutline.TreeViewElement.ExpandEvent):
|
188
|
+
void => {
|
189
|
+
const breakpoints = category && input.categories.get(category);
|
190
|
+
if (!breakpoints) {
|
191
|
+
return;
|
192
|
+
}
|
193
|
+
if (shouldExpandCategory(breakpoints)) {
|
194
|
+
// Basically ignore expand/collapse when the category is expanded by default.
|
195
|
+
return;
|
196
|
+
}
|
197
|
+
if (expanded) {
|
198
|
+
output.userExpandedCategories.add(category);
|
199
|
+
} else {
|
200
|
+
output.userExpandedCategories.delete(category);
|
201
|
+
}
|
202
|
+
};
|
209
203
|
|
210
204
|
render(
|
211
205
|
// clang-format off
|
@@ -219,17 +213,15 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
|
|
219
213
|
</devtools-toolbar>
|
220
214
|
<devtools-tree
|
221
215
|
${ref(e => { output.defaultFocus = e; })}
|
222
|
-
@expand=${onExpand}
|
223
216
|
.template=${html`
|
224
217
|
<ul role="tree">
|
225
218
|
${filteredCategories.map(([category, breakpoints]) => html`
|
226
|
-
<li
|
219
|
+
<li @expand=${(e: UI.TreeOutline.TreeViewElement.ExpandEvent) => onExpand(category, e)}
|
227
220
|
role="treeitem"
|
228
221
|
jslog-context=${category}
|
229
222
|
aria-checked=${breakpoints.some(breakpoint => breakpoint.enabled())
|
230
223
|
? breakpoints.some(breakpoint => !breakpoint.enabled()) ? 'mixed' : true
|
231
|
-
: false}
|
232
|
-
${trackCategoryConfigElement(category)}>
|
224
|
+
: false}>
|
233
225
|
<style>${categorizedBreakpointsSidebarPaneStyles}</style>
|
234
226
|
<devtools-checkbox
|
235
227
|
class="small"
|
@@ -192,7 +192,14 @@ export class BadgeNotification extends UI.Widget.Widget {
|
|
192
192
|
}
|
193
193
|
|
194
194
|
async #presentStarterBadge(badge: Badges.Badge): Promise<void> {
|
195
|
-
const
|
195
|
+
const getProfileResponse = await Host.GdpClient.GdpClient.instance().getProfile();
|
196
|
+
// The `getProfile` call failed and returned a `null`.
|
197
|
+
// For that case, we don't show anything.
|
198
|
+
if (!getProfileResponse) {
|
199
|
+
return;
|
200
|
+
}
|
201
|
+
|
202
|
+
const hasGdpProfile = Boolean(getProfileResponse.profile);
|
196
203
|
const receiveBadgesSettingEnabled = Badges.UserBadges.instance().isReceiveBadgesSettingEnabled();
|
197
204
|
const googleDeveloperProgramLink = UI.XLink.XLink.create(
|
198
205
|
'https://developers.google.com/program', lockedString('Google Developer Program'), 'badge-link', undefined,
|
@@ -200,14 +207,14 @@ export class BadgeNotification extends UI.Widget.Widget {
|
|
200
207
|
|
201
208
|
// If the user already has a GDP profile and the receive badges setting enabled,
|
202
209
|
// starter badge behaves as if it's an activity based badge.
|
203
|
-
if (
|
210
|
+
if (hasGdpProfile && receiveBadgesSettingEnabled) {
|
204
211
|
this.#presentActivityBasedBadge(badge);
|
205
212
|
return;
|
206
213
|
}
|
207
214
|
|
208
215
|
// If the user already has a GDP profile and the receive badges setting disabled,
|
209
216
|
// starter badge behaves as a nudge for opting into receiving badges.
|
210
|
-
if (
|
217
|
+
if (hasGdpProfile && !receiveBadgesSettingEnabled) {
|
211
218
|
this.#show({
|
212
219
|
message: i18nFormatString(
|
213
220
|
UIStrings.starterBadgeAwardMessageSettingDisabled, {PH1: badge.title, PH2: googleDeveloperProgramLink}),
|
@@ -1050,7 +1050,7 @@ let searchNetworkViewInstance: SearchNetworkView;
|
|
1050
1050
|
|
1051
1051
|
export class SearchNetworkView extends Search.SearchView.SearchView {
|
1052
1052
|
private constructor() {
|
1053
|
-
super('network'
|
1053
|
+
super('network');
|
1054
1054
|
}
|
1055
1055
|
|
1056
1056
|
static instance(opts: {
|
@@ -52,23 +52,24 @@ export type View = (input: ViewInput, output: unknown, target: HTMLElement) => v
|
|
52
52
|
export const DEFAULT_VIEW: View = (input, _output, target) => {
|
53
53
|
const {results, matches, expandedResults, onSelectMatch, onExpandSearchResult, onShowMoreMatches} = input;
|
54
54
|
|
55
|
-
const onExpand =
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
};
|
55
|
+
const onExpand =
|
56
|
+
(searchResult: SearchResult, {detail: {expanded}}: UI.TreeOutline.TreeViewElement.ExpandEvent): void => {
|
57
|
+
if (expanded) {
|
58
|
+
expandedResults.add(searchResult);
|
59
|
+
onExpandSearchResult(searchResult);
|
60
|
+
} else {
|
61
|
+
expandedResults.delete(searchResult);
|
62
|
+
}
|
63
|
+
};
|
65
64
|
|
66
65
|
// clang-format off
|
67
66
|
render(html`
|
68
|
-
<devtools-tree hide-overflow
|
67
|
+
<devtools-tree hide-overflow .template=${html`
|
69
68
|
<ul role="tree">
|
70
|
-
${results.map(
|
71
|
-
<li
|
69
|
+
${results.map(searchResult => html`
|
70
|
+
<li @expand=${(e: UI.TreeOutline.TreeViewElement.ExpandEvent) => onExpand(searchResult, e)}
|
71
|
+
role="treeitem"
|
72
|
+
class="search-result">
|
72
73
|
<style>${searchResultsPaneStyles}</style>
|
73
74
|
${renderSearchResult(searchResult)}
|
74
75
|
<ul role="group" ?hidden=${!expandedResults.has(searchResult)}>
|
@@ -293,12 +293,9 @@ export class SearchView extends UI.Widget.VBox {
|
|
293
293
|
}>;
|
294
294
|
#searchScope: SearchScope|null;
|
295
295
|
|
296
|
-
// We throttle adding search results, otherwise we trigger DOM layout for each
|
297
|
-
// result added.
|
298
|
-
#throttler: Common.Throttler.Throttler;
|
299
296
|
#searchResults: SearchResult[] = [];
|
300
297
|
|
301
|
-
constructor(settingKey: string,
|
298
|
+
constructor(settingKey: string, view = DEFAULT_VIEW) {
|
302
299
|
super({
|
303
300
|
jslog: `${VisualLogging.panel('search').track({resize: true})}`,
|
304
301
|
useShadowDom: true,
|
@@ -316,7 +313,6 @@ export class SearchView extends UI.Widget.VBox {
|
|
316
313
|
this.#searchConfig = null;
|
317
314
|
this.#pendingSearchConfig = null;
|
318
315
|
this.#progress = null;
|
319
|
-
this.#throttler = throttler;
|
320
316
|
|
321
317
|
this.#advancedSearchConfig = Common.Settings.Settings.instance().createLocalSetting(
|
322
318
|
settingKey + '-search-config', new Workspace.SearchConfig.SearchConfig('', true, false).toPlainObject());
|
@@ -451,17 +447,8 @@ export class SearchView extends UI.Widget.VBox {
|
|
451
447
|
return;
|
452
448
|
}
|
453
449
|
this.#searchResults.push(searchResult);
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
#setSearchResults(): void {
|
458
|
-
this.#searchMatchesCount = 0;
|
459
|
-
this.#searchResultsCount = 0;
|
460
|
-
this.#nonEmptySearchResultsCount = 0;
|
461
|
-
for (const searchResult of this.#searchResults) {
|
462
|
-
this.#addSearchResult(searchResult);
|
463
|
-
}
|
464
|
-
this.performUpdate();
|
450
|
+
this.#addSearchResult(searchResult);
|
451
|
+
this.requestUpdate();
|
465
452
|
}
|
466
453
|
|
467
454
|
#onSearchFinished(searchId: number, finished: boolean): void {
|
@@ -640,8 +627,4 @@ export class SearchView extends UI.Widget.VBox {
|
|
640
627
|
this.#resetSearch();
|
641
628
|
this.#onClearSearchInput();
|
642
629
|
}
|
643
|
-
|
644
|
-
get throttlerForTest(): Common.Throttler.Throttler {
|
645
|
-
return this.#throttler;
|
646
|
-
}
|
647
630
|
}
|
@@ -11,7 +11,6 @@ import type * as Common from '../../../core/common/common.js';
|
|
11
11
|
import * as Host from '../../../core/host/host.js';
|
12
12
|
import * as i18n from '../../../core/i18n/i18n.js';
|
13
13
|
import type * as Platform from '../../../core/platform/platform.js';
|
14
|
-
import * as Root from '../../../core/root/root.js';
|
15
14
|
import * as SDK from '../../../core/sdk/sdk.js';
|
16
15
|
import * as Badges from '../../../models/badges/badges.js';
|
17
16
|
import * as Buttons from '../../../ui/components/buttons/buttons.js';
|
@@ -206,8 +205,13 @@ export class SyncSection extends HTMLElement {
|
|
206
205
|
return;
|
207
206
|
}
|
208
207
|
|
209
|
-
|
210
|
-
|
208
|
+
const getProfileResponse = await Host.GdpClient.GdpClient.instance().getProfile();
|
209
|
+
if (!getProfileResponse) {
|
210
|
+
return;
|
211
|
+
}
|
212
|
+
|
213
|
+
this.#gdpProfile = getProfileResponse.profile ?? undefined;
|
214
|
+
this.#isEligibleToCreateGdpProfile = getProfileResponse.isEligible;
|
211
215
|
void ComponentHelpers.ScheduledRender.scheduleRender(this, this.#render);
|
212
216
|
}
|
213
217
|
}
|
@@ -310,9 +314,7 @@ function renderGdpSectionIfNeeded({
|
|
310
314
|
if (!Host.GdpClient.isGdpProfilesAvailable() || (!gdpProfile && !isEligibleToCreateProfile)) {
|
311
315
|
return Lit.nothing;
|
312
316
|
}
|
313
|
-
const hasReceiveBadgesCheckbox =
|
314
|
-
Host.GdpClient.getGdpProfilesEnterprisePolicy() === Root.Runtime.GdpProfilesEnterprisePolicyValue.ENABLED;
|
315
|
-
|
317
|
+
const hasReceiveBadgesCheckbox = Host.GdpClient.isBadgesEnabled() && receiveBadgesSetting;
|
316
318
|
function renderBrand(): Lit.LitTemplate {
|
317
319
|
// clang-format off
|
318
320
|
return html`
|
@@ -17,7 +17,7 @@ export class SearchSources {
|
|
17
17
|
|
18
18
|
export class SearchSourcesView extends Search.SearchView.SearchView {
|
19
19
|
constructor() {
|
20
|
-
super('sources'
|
20
|
+
super('sources');
|
21
21
|
}
|
22
22
|
|
23
23
|
override createScope(): Search.SearchScope.SearchScope {
|