chrome-devtools-frontend 1.0.1602348 → 1.0.1603822
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/version-control/SKILL.md +17 -2
- package/AUTHORS +1 -0
- package/front_end/core/common/Settings.ts +1 -871
- package/front_end/core/common/VersionController.ts +880 -0
- package/front_end/core/common/common.ts +2 -0
- package/front_end/core/platform/HostRuntime.ts +9 -3
- package/front_end/core/protocol_client/InspectorBackend.ts +8 -0
- package/front_end/core/root/Runtime.ts +5 -0
- package/front_end/core/sdk/OverlayModel.ts +13 -13
- package/front_end/core/sdk/OverlayPersistentHighlighter.ts +13 -10
- package/front_end/core/sdk/RuntimeModel.ts +5 -5
- package/front_end/core/sdk/ServiceWorkerManager.ts +4 -2
- package/front_end/core/sdk/Target.ts +5 -0
- package/front_end/core/sdk/TargetManager.ts +5 -0
- package/front_end/core/sdk/WebMCPModel.ts +104 -0
- package/front_end/core/sdk/sdk.ts +2 -0
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +13 -19
- package/front_end/generated/InspectorBackendCommands.ts +3 -0
- package/front_end/generated/protocol-mapping.d.ts +8 -0
- package/front_end/generated/protocol-proxy-api.d.ts +10 -0
- package/front_end/generated/protocol.ts +57 -0
- package/front_end/models/ai_assistance/AiConversation.ts +3 -3
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +50 -0
- package/front_end/models/ai_assistance/agents/AiAgent.ts +14 -1
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +19 -4
- package/front_end/models/ai_assistance/agents/NetworkAgent.ts +7 -1
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +30 -7
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +0 -23
- package/front_end/models/ai_assistance/data_formatters/LighthouseFormatter.snapshot.txt +60 -9
- package/front_end/models/ai_assistance/data_formatters/LighthouseFormatter.ts +71 -15
- package/front_end/models/heap_snapshot_model/HeapSnapshotModel.ts +7 -7
- package/front_end/models/javascript_metadata/NativeFunctions.js +6 -2
- package/front_end/models/lighthouse/LighthouseReporterTypes.ts +10 -8
- package/front_end/models/lighthouse/RunTypes.ts +3 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +13 -5
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +143 -18
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +30 -10
- package/front_end/panels/ai_assistance/components/chatMessage.css +58 -3
- package/front_end/panels/ai_assistance/components/walkthroughView.css +35 -5
- package/front_end/panels/application/AppManifestView.ts +2 -2
- package/front_end/panels/application/BackgroundServiceView.ts +9 -9
- package/front_end/panels/application/FrameDetailsView.ts +4 -13
- package/front_end/panels/application/IndexedDBViews.ts +1 -1
- package/front_end/panels/application/ServiceWorkerCacheViews.ts +3 -3
- package/front_end/panels/application/components/PermissionsPolicySection.ts +1 -1
- package/front_end/panels/application/components/permissionsPolicySection.css +54 -52
- package/front_end/panels/application/frameDetailsReportView.css +13 -1
- package/front_end/panels/common/ThrottlingUtils.ts +46 -0
- package/front_end/panels/common/common.ts +1 -0
- package/front_end/panels/elements/CSSValueTraceView.ts +9 -1
- package/front_end/panels/elements/ComputedStyleWidget.ts +11 -1
- package/front_end/panels/elements/PropertiesWidget.ts +14 -13
- package/front_end/panels/elements/PropertyRenderer.ts +10 -9
- package/front_end/panels/elements/StandaloneStylesContainer.ts +15 -5
- package/front_end/panels/elements/StylePropertiesSection.ts +0 -49
- package/front_end/panels/elements/StylePropertyTreeElement.ts +20 -0
- package/front_end/panels/elements/StylesContainer.ts +0 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +65 -31
- package/front_end/panels/elements/stylePropertiesTreeOutline.css +5 -0
- package/front_end/panels/issues/AffectedSelectivePermissionsInterventionView.ts +2 -2
- package/front_end/panels/lighthouse/LighthouseController.ts +4 -1
- package/front_end/panels/media/EventDisplayTable.ts +3 -2
- package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +14 -0
- package/front_end/panels/network/EventSourceMessagesView.ts +2 -2
- package/front_end/panels/network/ResourceChunkView.ts +1 -1
- package/front_end/panels/profiler/HeapDetachedElementsView.ts +9 -4
- package/front_end/panels/profiler/HeapProfileView.ts +8 -4
- package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +40 -33
- package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +1 -1
- package/front_end/panels/profiler/HeapSnapshotProxy.ts +1 -1
- package/front_end/panels/profiler/HeapSnapshotView.ts +12 -18
- package/front_end/panels/profiler/LiveHeapProfileView.ts +3 -4
- package/front_end/panels/profiler/ProfileHeader.ts +5 -11
- package/front_end/panels/profiler/ProfileView.ts +1 -10
- package/front_end/panels/sensors/SensorsView.ts +24 -43
- package/front_end/panels/settings/keybindsSettingsTab.css +25 -31
- package/front_end/panels/timeline/EventsTimelineTreeView.ts +2 -2
- package/front_end/panels/timeline/ThirdPartyTreeView.ts +8 -0
- package/front_end/panels/timeline/TimelinePanel.ts +14 -2
- package/front_end/panels/timeline/TimelineTreeView.ts +19 -17
- package/front_end/panels/timeline/components/FieldSettingsDialog.ts +5 -9
- package/front_end/panels/timeline/components/LiveMetricsView.ts +1 -2
- package/front_end/panels/timeline/components/OriginMap.ts +176 -159
- package/front_end/panels/timeline/components/originMap.css +4 -51
- package/front_end/panels/timeline/components/timelineRangeSummaryView.css +3 -1
- package/front_end/panels/timeline/thirdPartyTreeView.css +6 -0
- package/front_end/panels/timeline/timeline-meta.ts +11 -0
- package/front_end/panels/timeline/utils/Helpers.ts +5 -25
- package/front_end/panels/webauthn/WebauthnPane.ts +52 -0
- package/front_end/third_party/acorn/README.chromium +1 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/components/{list → lists}/List.ts +1 -1
- package/front_end/ui/components/{list → lists}/list.css +0 -1
- package/front_end/ui/legacy/Treeoutline.ts +7 -3
- package/front_end/ui/legacy/UIUtils.ts +13 -11
- package/front_end/ui/legacy/Widget.ts +5 -0
- package/front_end/ui/legacy/components/data_grid/DataGrid.ts +1 -1
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +3 -3
- package/front_end/ui/legacy/components/data_grid/SortableDataGrid.ts +2 -2
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +39 -23
- package/front_end/ui/legacy/components/perf_ui/GCActionDelegate.ts +20 -4
- package/front_end/ui/legacy/treeoutline.css +4 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
- package/package.json +1 -1
- /package/front_end/ui/components/{list → lists}/lists.ts +0 -0
|
@@ -384,15 +384,15 @@ export class BackgroundServiceView extends UI.Widget.VBox {
|
|
|
384
384
|
}
|
|
385
385
|
|
|
386
386
|
private createDataGrid(): DataGrid.DataGrid.DataGridImpl<EventData> {
|
|
387
|
-
const columns =
|
|
388
|
-
{id: 'id', title: '#', weight: 1},
|
|
389
|
-
{id: 'timestamp', title: i18nString(UIStrings.timestamp), weight: 7},
|
|
390
|
-
{id: 'event-name', title: i18nString(UIStrings.event), weight: 8},
|
|
391
|
-
{id: 'origin', title: i18nString(UIStrings.origin), weight: 8},
|
|
392
|
-
{id: 'storage-key', title: i18nString(UIStrings.storageKey), weight: 8},
|
|
393
|
-
{id: 'sw-scope', title: i18nString(UIStrings.swScope), weight: 4},
|
|
394
|
-
{id: 'instance-id', title: i18nString(UIStrings.instanceId), weight: 8},
|
|
395
|
-
]
|
|
387
|
+
const columns: DataGrid.DataGrid.ColumnDescriptor[] = [
|
|
388
|
+
{id: 'id', title: '#' as Common.UIString.LocalizedString, weight: 1, sortable: false},
|
|
389
|
+
{id: 'timestamp', title: i18nString(UIStrings.timestamp), weight: 7, sortable: false},
|
|
390
|
+
{id: 'event-name', title: i18nString(UIStrings.event), weight: 8, sortable: false},
|
|
391
|
+
{id: 'origin', title: i18nString(UIStrings.origin), weight: 8, sortable: false},
|
|
392
|
+
{id: 'storage-key', title: i18nString(UIStrings.storageKey), weight: 8, sortable: false},
|
|
393
|
+
{id: 'sw-scope', title: i18nString(UIStrings.swScope), weight: 4, sortable: false},
|
|
394
|
+
{id: 'instance-id', title: i18nString(UIStrings.instanceId), weight: 8, sortable: false},
|
|
395
|
+
];
|
|
396
396
|
const dataGrid = new DataGrid.DataGrid.DataGridImpl({
|
|
397
397
|
displayName: i18nString(UIStrings.backgroundServices),
|
|
398
398
|
columns,
|
|
@@ -268,7 +268,7 @@ export interface FrameDetailsReportViewData {
|
|
|
268
268
|
adScriptAncestry: Protocol.Network.AdAncestry|null;
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
-
interface FrameDetailsViewInput {
|
|
271
|
+
export interface FrameDetailsViewInput {
|
|
272
272
|
frame: SDK.ResourceTreeModel.ResourceTreeFrame;
|
|
273
273
|
target: SDK.Target.Target|null;
|
|
274
274
|
creationStackTrace: StackTrace.StackTrace.StackTrace|null;
|
|
@@ -282,9 +282,9 @@ interface FrameDetailsViewInput {
|
|
|
282
282
|
onRevealInSources: () => void;
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
-
type View = (input: FrameDetailsViewInput, output: undefined, target: HTMLElement) => void;
|
|
285
|
+
export type View = (input: FrameDetailsViewInput, output: undefined, target: HTMLElement) => void;
|
|
286
286
|
|
|
287
|
-
const DEFAULT_VIEW: View = (input, _output, target) => {
|
|
287
|
+
export const DEFAULT_VIEW: View = (input, _output, target) => {
|
|
288
288
|
if (!input.frame) {
|
|
289
289
|
return;
|
|
290
290
|
}
|
|
@@ -892,16 +892,7 @@ export class FrameDetailsReportView extends UI.Widget.Widget {
|
|
|
892
892
|
const result = await this.#frame?.parentFrame()?.getAdScriptAncestry(this.#frame?.id);
|
|
893
893
|
if (result && result.ancestryChain.length > 0) {
|
|
894
894
|
this.#adScriptAncestry = result;
|
|
895
|
-
|
|
896
|
-
// Obtain the Target associated with the first ad script, because in most scenarios all
|
|
897
|
-
// scripts share the same debuggerId. However, discrepancies might arise when content scripts
|
|
898
|
-
// from browser extensions are involved. We will monitor the debugging experiences and revisit
|
|
899
|
-
// this approach if it proves problematic.
|
|
900
|
-
const firstScript = this.#adScriptAncestry.ancestryChain[0];
|
|
901
|
-
const debuggerModel = firstScript?.debuggerId ?
|
|
902
|
-
await SDK.DebuggerModel.DebuggerModel.modelForDebuggerId(firstScript.debuggerId) :
|
|
903
|
-
null;
|
|
904
|
-
this.#target = debuggerModel?.target() ?? null;
|
|
895
|
+
this.#target = this.#frame?.resourceTreeModel().target() ?? null;
|
|
905
896
|
}
|
|
906
897
|
|
|
907
898
|
const frame = this.#frame;
|
|
@@ -320,7 +320,7 @@ export class IDBDataView extends UI.View.SimpleView {
|
|
|
320
320
|
private createDataGrid(): DataGrid.DataGrid.DataGridImpl<unknown> {
|
|
321
321
|
const keyPath = this.isIndex && this.index ? this.index.keyPath : this.objectStore.keyPath;
|
|
322
322
|
|
|
323
|
-
const columns
|
|
323
|
+
const columns: DataGrid.DataGrid.ColumnDescriptor[] = [];
|
|
324
324
|
|
|
325
325
|
// Create column defaults so that we avoid repetition below.
|
|
326
326
|
const columnDefaults: Partial<DataGrid.DataGrid.ColumnDescriptor> = {
|
|
@@ -210,8 +210,8 @@ export class ServiceWorkerCacheView extends UI.View.SimpleView {
|
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
private createDataGrid(): DataGrid.DataGrid.DataGridImpl<DataGridNode> {
|
|
213
|
-
const columns =
|
|
214
|
-
{id: 'number', title: '#', sortable: false, width: '3px'},
|
|
213
|
+
const columns: DataGrid.DataGrid.ColumnDescriptor[] = [
|
|
214
|
+
{id: 'number', title: '#' as Common.UIString.LocalizedString, sortable: false, width: '3px'},
|
|
215
215
|
{id: 'name', title: i18nString(UIStrings.name), weight: 4, sortable: true},
|
|
216
216
|
{
|
|
217
217
|
id: 'response-type',
|
|
@@ -237,7 +237,7 @@ export class ServiceWorkerCacheView extends UI.View.SimpleView {
|
|
|
237
237
|
sortable: true,
|
|
238
238
|
},
|
|
239
239
|
{id: 'vary-header', title: i18n.i18n.lockedString('Vary Header'), weight: 1, sortable: true},
|
|
240
|
-
]
|
|
240
|
+
];
|
|
241
241
|
const dataGrid = new DataGrid.DataGrid.DataGridImpl({
|
|
242
242
|
displayName: i18nString(UIStrings.serviceWorkerCache),
|
|
243
243
|
columns,
|
|
@@ -219,7 +219,7 @@ export class PermissionsPolicySection extends UI.Widget.Widget {
|
|
|
219
219
|
#view: View;
|
|
220
220
|
|
|
221
221
|
constructor(element?: HTMLElement, view = DEFAULT_VIEW) {
|
|
222
|
-
super(element, {useShadowDom:
|
|
222
|
+
super(element, {useShadowDom: false});
|
|
223
223
|
this.#view = view;
|
|
224
224
|
}
|
|
225
225
|
|
|
@@ -4,56 +4,58 @@
|
|
|
4
4
|
* found in the LICENSE file.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
7
|
+
@scope to (devtools-widget > *) {
|
|
8
|
+
:scope {
|
|
9
|
+
display: contents;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.text-ellipsis {
|
|
13
|
+
overflow: hidden;
|
|
14
|
+
text-overflow: ellipsis;
|
|
15
|
+
white-space: nowrap;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.link,
|
|
19
|
+
.devtools-link {
|
|
20
|
+
color: var(--sys-color-primary);
|
|
21
|
+
text-decoration: underline;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
outline-offset: 2px;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
button.link {
|
|
27
|
+
border: none;
|
|
28
|
+
background: none;
|
|
29
|
+
font-family: inherit;
|
|
30
|
+
font-size: inherit;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.policies-list {
|
|
34
|
+
padding-top: 3px;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.permissions-row {
|
|
38
|
+
display: flex;
|
|
39
|
+
line-height: 22px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.permissions-row div {
|
|
43
|
+
padding-right: 5px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.feature-name {
|
|
47
|
+
width: 135px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.allowed-icon {
|
|
51
|
+
vertical-align: sub;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.block-reason {
|
|
55
|
+
width: 215px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.disabled-features-button {
|
|
59
|
+
padding-left: var(--sys-size-3);
|
|
60
|
+
}
|
|
59
61
|
}
|
|
@@ -79,6 +79,18 @@ button.text-link {
|
|
|
79
79
|
display: flex;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
.inline-items devtools-button {
|
|
83
|
+
flex: 0 0 20px;
|
|
84
|
+
width: 20px;
|
|
85
|
+
height: 20px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.inline-items .text-ellipsis {
|
|
89
|
+
flex: 0 1 auto;
|
|
90
|
+
min-width: 0;
|
|
91
|
+
padding-left: 2px;
|
|
92
|
+
}
|
|
93
|
+
|
|
82
94
|
.span-cols {
|
|
83
95
|
grid-column-start: span 2;
|
|
84
96
|
margin-left: var(--sys-size-9);
|
|
@@ -115,4 +127,4 @@ button.text-link {
|
|
|
115
127
|
color: linktext;
|
|
116
128
|
text-decoration-color: linktext;
|
|
117
129
|
}
|
|
118
|
-
}
|
|
130
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Copyright 2026 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 * as CrUXManager from '../../models/crux-manager/crux-manager.js';
|
|
7
|
+
|
|
8
|
+
export interface ThrottlingRecommendations {
|
|
9
|
+
cpuOption: SDK.CPUThrottlingManager.CPUThrottlingOption|null;
|
|
10
|
+
networkConditions: SDK.NetworkManager.Conditions|null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Computes the recommended CPU and network throttling presets based on CrUX
|
|
15
|
+
* field metric data.
|
|
16
|
+
*/
|
|
17
|
+
export function getThrottlingRecommendations(): ThrottlingRecommendations {
|
|
18
|
+
const cruxManager = CrUXManager.CrUXManager.instance();
|
|
19
|
+
const roundTripTimeMetricData = cruxManager.getSelectedFieldMetricData('round_trip_time');
|
|
20
|
+
|
|
21
|
+
let cpuOption: SDK.CPUThrottlingManager.CPUThrottlingOption =
|
|
22
|
+
SDK.CPUThrottlingManager.CalibratedMidTierMobileThrottlingOption;
|
|
23
|
+
if (cpuOption.rate() === 0) {
|
|
24
|
+
cpuOption = SDK.CPUThrottlingManager.MidTierThrottlingOption;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const networkConditions = getRecommendedNetworkConditions(roundTripTimeMetricData);
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
cpuOption,
|
|
31
|
+
networkConditions,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Computes the recommended network throttling preset based on CrUX RTT field
|
|
37
|
+
* metric data. Returns null if no RTT data is available or no preset matches.
|
|
38
|
+
*/
|
|
39
|
+
export function getRecommendedNetworkConditions(roundTripTimeMetricData?: CrUXManager.MetricResponse):
|
|
40
|
+
SDK.NetworkManager.Conditions|null {
|
|
41
|
+
if (roundTripTimeMetricData?.percentiles) {
|
|
42
|
+
const rtt = Number(roundTripTimeMetricData.percentiles.p75);
|
|
43
|
+
return SDK.NetworkManager.getRecommendedNetworkPreset(rtt);
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
@@ -109,5 +109,6 @@ export * as ExtensionServer from './ExtensionServer.js';
|
|
|
109
109
|
export * as ExtensionView from './ExtensionView.js';
|
|
110
110
|
export * as PersistenceUtils from './PersistenceUtils.js';
|
|
111
111
|
export * as DOMLinkifier from './DOMLinkifier.js';
|
|
112
|
+
export * as ThrottlingUtils from './ThrottlingUtils.js';
|
|
112
113
|
export * as ExtensionIframe from './ExtensionView.js';
|
|
113
114
|
export {CopyChangesToPrompt} from './CopyChangesToPrompt.js';
|
|
@@ -128,6 +128,7 @@ export class CSSValueTraceView extends UI.Widget.VBox {
|
|
|
128
128
|
expandPercentagesInShorthands: boolean,
|
|
129
129
|
shorthandPositionOffset: number,
|
|
130
130
|
focus: boolean,
|
|
131
|
+
signal?: AbortSignal,
|
|
131
132
|
): Promise<void> {
|
|
132
133
|
const matchedResult = subexpression === null ?
|
|
133
134
|
property.parseValue(matchedStyles, computedStyles) :
|
|
@@ -136,7 +137,7 @@ export class CSSValueTraceView extends UI.Widget.VBox {
|
|
|
136
137
|
return undefined;
|
|
137
138
|
}
|
|
138
139
|
return await this.#showTrace(
|
|
139
|
-
property, matchedResult, renderers, expandPercentagesInShorthands, shorthandPositionOffset, focus);
|
|
140
|
+
property, matchedResult, renderers, expandPercentagesInShorthands, shorthandPositionOffset, focus, signal);
|
|
140
141
|
}
|
|
141
142
|
|
|
142
143
|
async #showTrace(
|
|
@@ -146,6 +147,7 @@ export class CSSValueTraceView extends UI.Widget.VBox {
|
|
|
146
147
|
expandPercentagesInShorthands: boolean,
|
|
147
148
|
shorthandPositionOffset: number,
|
|
148
149
|
focus: boolean,
|
|
150
|
+
signal?: AbortSignal,
|
|
149
151
|
): Promise<void> {
|
|
150
152
|
this.#highlighting = new Highlighting();
|
|
151
153
|
const rendererMap = new Map(renderers.map(r => [r.matchType, r]));
|
|
@@ -165,6 +167,7 @@ export class CSSValueTraceView extends UI.Widget.VBox {
|
|
|
165
167
|
/* cssControls */ undefined,
|
|
166
168
|
/* options */ {},
|
|
167
169
|
tracing,
|
|
170
|
+
signal,
|
|
168
171
|
);
|
|
169
172
|
substitutions.push(Renderer.render(matchedResult.ast.tree, context).nodes);
|
|
170
173
|
}
|
|
@@ -180,6 +183,7 @@ export class CSSValueTraceView extends UI.Widget.VBox {
|
|
|
180
183
|
/* cssControls */ undefined,
|
|
181
184
|
/* options */ {},
|
|
182
185
|
tracing,
|
|
186
|
+
signal,
|
|
183
187
|
);
|
|
184
188
|
evaluations.push(Renderer.render(matchedResult.ast.tree, context).nodes);
|
|
185
189
|
asyncCallbackResults.push(tracing.runAsyncEvaluations());
|
|
@@ -199,6 +203,10 @@ export class CSSValueTraceView extends UI.Widget.VBox {
|
|
|
199
203
|
property,
|
|
200
204
|
rendererMap,
|
|
201
205
|
matchedResult,
|
|
206
|
+
undefined,
|
|
207
|
+
{},
|
|
208
|
+
undefined,
|
|
209
|
+
signal,
|
|
202
210
|
);
|
|
203
211
|
this.#evaluations.push(Renderer.render(matchedResult.ast.tree, context).nodes);
|
|
204
212
|
}
|
|
@@ -331,6 +331,7 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
331
331
|
|
|
332
332
|
#computedStylesTree = new TreeOutline.TreeOutline.TreeOutline<ComputedStyleData>();
|
|
333
333
|
#treeData?: TreeOutline.TreeOutline.TreeOutlineData<ComputedStyleData>;
|
|
334
|
+
#enableNarrowViewResizing = true;
|
|
334
335
|
readonly #view: View;
|
|
335
336
|
|
|
336
337
|
/**
|
|
@@ -378,10 +379,19 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
378
379
|
}
|
|
379
380
|
|
|
380
381
|
override onResize(): void {
|
|
381
|
-
const isNarrow = this.contentElement.offsetWidth < 260;
|
|
382
|
+
const isNarrow = this.#enableNarrowViewResizing && this.contentElement.offsetWidth < 260;
|
|
382
383
|
this.#computedStylesTree.classList.toggle('computed-narrow', isNarrow);
|
|
383
384
|
}
|
|
384
385
|
|
|
386
|
+
get enableNarrowViewResizing(): boolean {
|
|
387
|
+
return this.#enableNarrowViewResizing;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
set enableNarrowViewResizing(enable: boolean) {
|
|
391
|
+
this.#enableNarrowViewResizing = enable;
|
|
392
|
+
this.onResize();
|
|
393
|
+
}
|
|
394
|
+
|
|
385
395
|
get filterText(): RegExp|string {
|
|
386
396
|
if (this.#filterIsRegex) {
|
|
387
397
|
return new RegExp(this.#filterText);
|
|
@@ -40,7 +40,7 @@ import * as Platform from '../../core/platform/platform.js';
|
|
|
40
40
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
41
41
|
import * as ObjectUI from '../../ui/legacy/components/object_ui/object_ui.js';
|
|
42
42
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
43
|
-
import {html, nothing, render} from '../../ui/lit/lit.js';
|
|
43
|
+
import {Directives, html, nothing, render} from '../../ui/lit/lit.js';
|
|
44
44
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
45
45
|
|
|
46
46
|
import propertiesWidgetStyles from './propertiesWidget.css.js';
|
|
@@ -48,6 +48,7 @@ import propertiesWidgetStyles from './propertiesWidget.css.js';
|
|
|
48
48
|
const OBJECT_GROUP_NAME = 'properties-sidebar-pane';
|
|
49
49
|
|
|
50
50
|
const {bindToSetting} = UI.UIUtils;
|
|
51
|
+
const {repeat} = Directives;
|
|
51
52
|
|
|
52
53
|
const UIStrings = {
|
|
53
54
|
/**
|
|
@@ -75,7 +76,6 @@ interface PropertiesWidgetInput {
|
|
|
75
76
|
onFilterChanged: (e: CustomEvent<string>) => void;
|
|
76
77
|
onRegexToggled: () => void;
|
|
77
78
|
isRegex: boolean;
|
|
78
|
-
treeOutline: ObjectUI.ObjectPropertiesSection.ObjectPropertiesSectionsTreeOutline;
|
|
79
79
|
objectTree: ObjectUI.ObjectPropertiesSection.ObjectTree|null;
|
|
80
80
|
allChildrenFiltered: boolean;
|
|
81
81
|
}
|
|
@@ -103,7 +103,17 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
|
|
|
103
103
|
${input.objectTree && input.allChildrenFiltered ? html`
|
|
104
104
|
<div class="gray-info-message">${i18nString(UIStrings.noMatchingProperty)}</div>
|
|
105
105
|
` : nothing}
|
|
106
|
-
|
|
106
|
+
<devtools-tree .template=${html`
|
|
107
|
+
<ul role=tree class="source-code object-properties-section">
|
|
108
|
+
<style>${ObjectUI.ObjectPropertiesSection.objectValueStyles}</style>;
|
|
109
|
+
<style>${ObjectUI.ObjectPropertiesSection.objectPropertiesSectionStyles}</style>;
|
|
110
|
+
${repeat(ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement.createPropertyNodes(
|
|
111
|
+
input.objectTree?.children ?? {},
|
|
112
|
+
true /* skipProto */,
|
|
113
|
+
true /* skipGettersAndSetters */),
|
|
114
|
+
node => html`<devtools-tree-wrapper .treeElement=${node}></devtools-tree-wrapper>`)}
|
|
115
|
+
</ul>
|
|
116
|
+
`}></devtools-tree>
|
|
107
117
|
</div>`, target);
|
|
108
118
|
// clang-format on
|
|
109
119
|
};
|
|
@@ -218,15 +228,7 @@ export class PropertiesWidget extends UI.Widget.VBox {
|
|
|
218
228
|
|
|
219
229
|
override async performUpdate(): Promise<void> {
|
|
220
230
|
await this.#updateNodeIfRequired();
|
|
221
|
-
|
|
222
|
-
this.treeOutline.removeChildren();
|
|
223
|
-
} else {
|
|
224
|
-
const treeElement = this.treeOutline.rootElement();
|
|
225
|
-
treeElement.removeChildren();
|
|
226
|
-
ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement.populateWithProperties(
|
|
227
|
-
treeElement, await this.#objectTree.populateChildrenIfNeeded(), true /* skipProto */,
|
|
228
|
-
true /* skipGettersAndSetters */);
|
|
229
|
-
}
|
|
231
|
+
await this.#objectTree?.populateChildrenIfNeeded();
|
|
230
232
|
const allChildrenFiltered =
|
|
231
233
|
!(this.#objectTree?.children?.accessors?.some(c => !c.isFiltered) ||
|
|
232
234
|
this.#objectTree?.children?.arrayRanges?.some(() => true) ||
|
|
@@ -237,7 +239,6 @@ export class PropertiesWidget extends UI.Widget.VBox {
|
|
|
237
239
|
onFilterChanged: this.onFilterChanged.bind(this),
|
|
238
240
|
onRegexToggled: this.onRegexToggled.bind(this),
|
|
239
241
|
isRegex: this.#isRegex,
|
|
240
|
-
treeOutline: this.treeOutline,
|
|
241
242
|
allChildrenFiltered,
|
|
242
243
|
objectTree: this.#objectTree,
|
|
243
244
|
},
|
|
@@ -354,7 +354,7 @@ export class RenderingContext {
|
|
|
354
354
|
MatchRenderer<SDK.CSSPropertyParser.Match>>,
|
|
355
355
|
readonly matchedResult: SDK.CSSPropertyParser.BottomUpTreeMatching,
|
|
356
356
|
readonly cssControls?: SDK.CSSPropertyParser.CSSControlMap, readonly options: {readonly?: boolean} = {},
|
|
357
|
-
readonly tracing?: TracingContext) {
|
|
357
|
+
readonly tracing?: TracingContext, readonly signal?: AbortSignal) {
|
|
358
358
|
}
|
|
359
359
|
|
|
360
360
|
addControl(cssType: string, control: HTMLElement): void {
|
|
@@ -414,11 +414,12 @@ export class Renderer extends SDK.CSSPropertyParser.TreeWalker {
|
|
|
414
414
|
readonly?: boolean,
|
|
415
415
|
},
|
|
416
416
|
tracing: TracingContext|undefined,
|
|
417
|
+
signal: AbortSignal|undefined,
|
|
417
418
|
) {
|
|
418
419
|
super(ast);
|
|
419
420
|
this.#matchedResult = matchedResult;
|
|
420
421
|
this.#context =
|
|
421
|
-
new RenderingContext(this.ast, property, renderers, this.#matchedResult, cssControls, options, tracing);
|
|
422
|
+
new RenderingContext(this.ast, property, renderers, this.#matchedResult, cssControls, options, tracing, signal);
|
|
422
423
|
}
|
|
423
424
|
|
|
424
425
|
static render(nodeOrNodes: CodeMirror.SyntaxNode|CodeMirror.SyntaxNode[], context: RenderingContext):
|
|
@@ -430,7 +431,7 @@ export class Renderer extends SDK.CSSPropertyParser.TreeWalker {
|
|
|
430
431
|
const renderers = nodeOrNodes.map(
|
|
431
432
|
node => this.walkExcludingSuccessors(
|
|
432
433
|
context.ast.subtree(node), context.property, context.renderers, context.matchedResult, cssControls,
|
|
433
|
-
context.options, context.tracing));
|
|
434
|
+
context.options, context.tracing, context.signal));
|
|
434
435
|
const nodes = renderers.map(node => node.#output).reduce(mergeWithSpacing, []);
|
|
435
436
|
return {nodes, cssControls};
|
|
436
437
|
}
|
|
@@ -491,8 +492,8 @@ export class Renderer extends SDK.CSSPropertyParser.TreeWalker {
|
|
|
491
492
|
static renderValueElement(
|
|
492
493
|
property: SDK.CSSProperty.CSSProperty|{name: string, value: string},
|
|
493
494
|
matchedResult: SDK.CSSPropertyParser.BottomUpTreeMatching|null,
|
|
494
|
-
renderers: Array<MatchRenderer<SDK.CSSPropertyParser.Match>>,
|
|
495
|
-
|
|
495
|
+
renderers: Array<MatchRenderer<SDK.CSSPropertyParser.Match>>, tracing?: TracingContext,
|
|
496
|
+
signal?: AbortSignal): {valueElement: HTMLElement, cssControls: SDK.CSSPropertyParser.CSSControlMap} {
|
|
496
497
|
const valueElement = document.createElement('span');
|
|
497
498
|
valueElement.setAttribute(
|
|
498
499
|
'jslog', `${VisualLogging.value().track({
|
|
@@ -502,7 +503,7 @@ export class Renderer extends SDK.CSSPropertyParser.TreeWalker {
|
|
|
502
503
|
UI.ARIAUtils.setLabel(valueElement, i18nString(UIStrings.cssPropertyValue, {PH1: property.value}));
|
|
503
504
|
valueElement.className = 'value';
|
|
504
505
|
valueElement.tabIndex = -1;
|
|
505
|
-
const {nodes, cssControls} = this.renderValueNodes(property, matchedResult, renderers, tracing);
|
|
506
|
+
const {nodes, cssControls} = this.renderValueNodes(property, matchedResult, renderers, tracing, signal);
|
|
506
507
|
nodes.forEach(node => valueElement.appendChild(node));
|
|
507
508
|
valueElement.normalize();
|
|
508
509
|
return {valueElement, cssControls};
|
|
@@ -511,8 +512,8 @@ export class Renderer extends SDK.CSSPropertyParser.TreeWalker {
|
|
|
511
512
|
static renderValueNodes(
|
|
512
513
|
property: SDK.CSSProperty.CSSProperty|{name: string, value: string},
|
|
513
514
|
matchedResult: SDK.CSSPropertyParser.BottomUpTreeMatching|null,
|
|
514
|
-
renderers: Array<MatchRenderer<SDK.CSSPropertyParser.Match>>,
|
|
515
|
-
|
|
515
|
+
renderers: Array<MatchRenderer<SDK.CSSPropertyParser.Match>>, tracing?: TracingContext,
|
|
516
|
+
signal?: AbortSignal): {nodes: Node[], cssControls: SDK.CSSPropertyParser.CSSControlMap} {
|
|
516
517
|
if (!matchedResult) {
|
|
517
518
|
return {nodes: [document.createTextNode(property.value)], cssControls: new Map()};
|
|
518
519
|
}
|
|
@@ -524,7 +525,7 @@ export class Renderer extends SDK.CSSPropertyParser.TreeWalker {
|
|
|
524
525
|
|
|
525
526
|
const context = new RenderingContext(
|
|
526
527
|
matchedResult.ast, property instanceof SDK.CSSProperty.CSSProperty ? property : null, rendererMap,
|
|
527
|
-
matchedResult, undefined, {}, tracing);
|
|
528
|
+
matchedResult, undefined, {}, tracing, signal);
|
|
528
529
|
return Renderer.render([matchedResult.ast.tree, ...matchedResult.ast.trailingNodes], context);
|
|
529
530
|
}
|
|
530
531
|
}
|
|
@@ -114,10 +114,7 @@ export class StandaloneStylesContainer extends Common.ObjectWrapper.eventMixin<E
|
|
|
114
114
|
return this.#webCustomData;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
async #updateSections(): Promise<void> {
|
|
118
|
-
for (const section of this.#sections) {
|
|
119
|
-
section.dispose();
|
|
120
|
-
}
|
|
117
|
+
async #updateSections(signal?: AbortSignal): Promise<void> {
|
|
121
118
|
const node = this.node();
|
|
122
119
|
if (!node) {
|
|
123
120
|
this.#sections = [];
|
|
@@ -126,6 +123,10 @@ export class StandaloneStylesContainer extends Common.ObjectWrapper.eventMixin<E
|
|
|
126
123
|
|
|
127
124
|
const cssModel = node.domModel().cssModel();
|
|
128
125
|
const matchedStyles = await cssModel.cachedMatchedCascadeForNode(node);
|
|
126
|
+
if (signal?.aborted) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
129
130
|
const parentNodeId = matchedStyles?.getParentLayoutNodeId();
|
|
130
131
|
|
|
131
132
|
const [parentStyles, computedStyles, extraStyles] = await Promise.all([
|
|
@@ -133,6 +134,10 @@ export class StandaloneStylesContainer extends Common.ObjectWrapper.eventMixin<E
|
|
|
133
134
|
cssModel.getComputedStyleExtraFields(node.id)
|
|
134
135
|
]);
|
|
135
136
|
|
|
137
|
+
if (signal?.aborted) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
136
141
|
if (!matchedStyles) {
|
|
137
142
|
return;
|
|
138
143
|
}
|
|
@@ -142,6 +147,7 @@ export class StandaloneStylesContainer extends Common.ObjectWrapper.eventMixin<E
|
|
|
142
147
|
for (const style of matchedStyles.nodeStyles()) {
|
|
143
148
|
const section = new StylePropertiesSection(
|
|
144
149
|
this, matchedStyles, style, sectionIdx++, computedStyles, parentStyles, extraStyles);
|
|
150
|
+
section.update(true);
|
|
145
151
|
newSections.push(section);
|
|
146
152
|
this.sectionByElement.set(section.element, section);
|
|
147
153
|
}
|
|
@@ -150,7 +156,10 @@ export class StandaloneStylesContainer extends Common.ObjectWrapper.eventMixin<E
|
|
|
150
156
|
this.swatchPopoverHelper().reposition();
|
|
151
157
|
}
|
|
152
158
|
|
|
153
|
-
override async performUpdate(): Promise<void> {
|
|
159
|
+
override async performUpdate(signal?: AbortSignal): Promise<void> {
|
|
160
|
+
await this.#updateSections(signal);
|
|
161
|
+
signal?.throwIfAborted();
|
|
162
|
+
|
|
154
163
|
const viewInput: ViewInput = {
|
|
155
164
|
sections: this.#sections.filter(section => !section.isHidden()),
|
|
156
165
|
};
|
|
@@ -178,6 +187,7 @@ export class StandaloneStylesContainer extends Common.ObjectWrapper.eventMixin<E
|
|
|
178
187
|
return;
|
|
179
188
|
}
|
|
180
189
|
this.#computedStyleModelInternal.node = node;
|
|
190
|
+
this.forceUpdate();
|
|
181
191
|
}
|
|
182
192
|
|
|
183
193
|
set filter(regex: RegExp|null) {
|
|
@@ -44,7 +44,6 @@ import * as SDK from '../../core/sdk/sdk.js';
|
|
|
44
44
|
import * as Protocol from '../../generated/protocol.js';
|
|
45
45
|
import * as Badges from '../../models/badges/badges.js';
|
|
46
46
|
import * as Bindings from '../../models/bindings/bindings.js';
|
|
47
|
-
import * as ComputedStyle from '../../models/computed_style/computed_style.js';
|
|
48
47
|
import * as TextUtils from '../../models/text_utils/text_utils.js';
|
|
49
48
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
50
49
|
import * as Tooltips from '../../ui/components/tooltips/tooltips.js';
|
|
@@ -375,55 +374,12 @@ export class StylePropertiesSection {
|
|
|
375
374
|
this.markSelectorMatches();
|
|
376
375
|
this.onpopulate();
|
|
377
376
|
this.#updateCollapsedState();
|
|
378
|
-
|
|
379
|
-
this.stylesContainer.computedStyleModel().addEventListener(
|
|
380
|
-
ComputedStyle.ComputedStyleModel.Events.CSS_MODEL_CHANGED, this.#onCSSModelChanged, this);
|
|
381
377
|
}
|
|
382
378
|
|
|
383
379
|
setComputedStyles(computedStyles: Map<string, string>|null): void {
|
|
384
380
|
this.computedStyles = computedStyles;
|
|
385
381
|
}
|
|
386
382
|
|
|
387
|
-
#onCSSModelChanged(event: Common.EventTarget.EventTargetEvent<ComputedStyle.ComputedStyleModel.CSSModelChangedEvent>):
|
|
388
|
-
void {
|
|
389
|
-
const edit = event?.data && 'edit' in event.data ? event.data.edit : null;
|
|
390
|
-
if (edit) {
|
|
391
|
-
this.styleSheetEdited(edit);
|
|
392
|
-
void this.refreshComputedValues();
|
|
393
|
-
return;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
if (this.stylesContainer.isEditingStyle || this.stylesContainer.userOperation) {
|
|
397
|
-
void this.refreshComputedValues();
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
async refreshComputedValues(): Promise<void> {
|
|
402
|
-
const node = this.stylesContainer.node();
|
|
403
|
-
if (!node) {
|
|
404
|
-
return;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
const cssModel = node.domModel().cssModel();
|
|
408
|
-
const computedStyleModel = this.stylesContainer.computedStyleModel();
|
|
409
|
-
|
|
410
|
-
const matchedStyles = await cssModel.cachedMatchedCascadeForNode(node);
|
|
411
|
-
const parentNodeId = matchedStyles?.getParentLayoutNodeId();
|
|
412
|
-
|
|
413
|
-
const [computedStyles, parentsComputedStyles] = await Promise.all([
|
|
414
|
-
computedStyleModel.fetchComputedStyle(),
|
|
415
|
-
parentNodeId ? cssModel.getComputedStyle(parentNodeId) : null,
|
|
416
|
-
]);
|
|
417
|
-
|
|
418
|
-
if (computedStyles) {
|
|
419
|
-
this.setComputedStyles(computedStyles.computedStyle);
|
|
420
|
-
}
|
|
421
|
-
if (parentsComputedStyles) {
|
|
422
|
-
this.setParentsComputedStyles(parentsComputedStyles);
|
|
423
|
-
}
|
|
424
|
-
this.updateAuthoringHint();
|
|
425
|
-
}
|
|
426
|
-
|
|
427
383
|
setParentsComputedStyles(parentsComputedStyles: Map<string, string>|null): void {
|
|
428
384
|
this.parentsComputedStyles = parentsComputedStyles;
|
|
429
385
|
}
|
|
@@ -444,11 +400,6 @@ export class StylePropertiesSection {
|
|
|
444
400
|
}
|
|
445
401
|
}
|
|
446
402
|
|
|
447
|
-
dispose(): void {
|
|
448
|
-
this.stylesContainer.computedStyleModel().removeEventListener(
|
|
449
|
-
ComputedStyle.ComputedStyleModel.Events.CSS_MODEL_CHANGED, this.#onCSSModelChanged, this);
|
|
450
|
-
}
|
|
451
|
-
|
|
452
403
|
setSectionIdx(sectionIdx: number): void {
|
|
453
404
|
this.sectionIdx = sectionIdx;
|
|
454
405
|
this.onpopulate();
|