chrome-devtools-frontend 1.0.1602543 → 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/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/TargetManager.ts +5 -0
- package/front_end/core/sdk/WebMCPModel.ts +6 -0
- 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/agents/PerformanceAgent.ts +16 -5
- 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/javascript_metadata/NativeFunctions.js +6 -2
- package/front_end/models/lighthouse/LighthouseReporterTypes.ts +10 -8
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +4 -3
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +83 -19
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +30 -10
- package/front_end/panels/ai_assistance/components/chatMessage.css +33 -7
- package/front_end/panels/ai_assistance/components/walkthroughView.css +35 -5
- package/front_end/panels/common/ThrottlingUtils.ts +46 -0
- package/front_end/panels/common/common.ts +1 -0
- package/front_end/panels/elements/ComputedStyleWidget.ts +11 -1
- package/front_end/panels/elements/StandaloneStylesContainer.ts +0 -3
- package/front_end/panels/elements/StylePropertiesSection.ts +0 -49
- package/front_end/panels/elements/StylesContainer.ts +0 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +32 -7
- package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +14 -0
- package/front_end/panels/profiler/ProfileView.ts +0 -9
- package/front_end/panels/settings/keybindsSettingsTab.css +25 -31
- package/front_end/panels/timeline/ThirdPartyTreeView.ts +8 -0
- package/front_end/panels/timeline/TimelinePanel.ts +14 -2
- 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/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/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/components/data_grid/DataGridElement.ts +3 -3
- package/package.json +1 -1
- /package/front_end/ui/components/{list → lists}/lists.ts +0 -0
|
@@ -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';
|
|
@@ -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);
|
|
@@ -115,9 +115,6 @@ export class StandaloneStylesContainer extends Common.ObjectWrapper.eventMixin<E
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
async #updateSections(signal?: AbortSignal): Promise<void> {
|
|
118
|
-
for (const section of this.#sections) {
|
|
119
|
-
section.dispose();
|
|
120
|
-
}
|
|
121
118
|
const node = this.node();
|
|
122
119
|
if (!node) {
|
|
123
120
|
this.#sections = [];
|
|
@@ -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();
|
|
@@ -17,7 +17,6 @@ export interface StylesContainer {
|
|
|
17
17
|
activeCSSAngle: InlineEditor.CSSAngle.CSSAngle|null;
|
|
18
18
|
readonly webCustomData: WebCustomData|undefined;
|
|
19
19
|
isEditingStyle: boolean;
|
|
20
|
-
userOperation: boolean;
|
|
21
20
|
readonly sectionByElement: WeakMap<Node, StylePropertiesSection>;
|
|
22
21
|
readonly element: HTMLElement;
|
|
23
22
|
readonly linkifier: Components.Linkifier.Linkifier;
|
|
@@ -189,7 +189,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
|
|
|
189
189
|
private readonly decorator: StylePropertyHighlighter;
|
|
190
190
|
|
|
191
191
|
private lastRevealedProperty: SDK.CSSProperty.CSSProperty|null = null;
|
|
192
|
-
userOperation = false;
|
|
192
|
+
private userOperation = false;
|
|
193
193
|
isEditingStyle = false;
|
|
194
194
|
#filterRegex: RegExp|null = null;
|
|
195
195
|
#isRegex = false;
|
|
@@ -211,6 +211,8 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
|
|
|
211
211
|
#webCustomData?: WebCustomData;
|
|
212
212
|
|
|
213
213
|
activeCSSAngle: InlineEditor.CSSAngle.CSSAngle|null = null;
|
|
214
|
+
#updateAbortController?: AbortController;
|
|
215
|
+
#updateComputedStylesAbortController?: AbortController;
|
|
214
216
|
|
|
215
217
|
constructor(computedStyleModel: ComputedStyle.ComputedStyleModel.ComputedStyleModel) {
|
|
216
218
|
super(computedStyleModel, {delegatesFocus: true});
|
|
@@ -688,9 +690,12 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
|
|
|
688
690
|
|
|
689
691
|
override onCSSModelChanged(
|
|
690
692
|
event: Common.EventTarget.EventTargetEvent<ComputedStyle.ComputedStyleModel.CSSModelChangedEvent>): void {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
693
|
+
const edit = event?.data && 'edit' in event.data ? event.data.edit : null;
|
|
694
|
+
if (edit) {
|
|
695
|
+
for (const section of this.allSections()) {
|
|
696
|
+
section.styleSheetEdited(edit);
|
|
697
|
+
}
|
|
698
|
+
void this.#refreshComputedStyles();
|
|
694
699
|
return;
|
|
695
700
|
}
|
|
696
701
|
|
|
@@ -713,6 +718,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
|
|
|
713
718
|
|
|
714
719
|
#resetUpdateIfNotEditing(): void {
|
|
715
720
|
if (this.userOperation || this.isEditingStyle) {
|
|
721
|
+
void this.#refreshComputedStyles();
|
|
716
722
|
return;
|
|
717
723
|
}
|
|
718
724
|
|
|
@@ -861,6 +867,28 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
|
|
|
861
867
|
}
|
|
862
868
|
}
|
|
863
869
|
|
|
870
|
+
async #refreshComputedStyles(): Promise<void> {
|
|
871
|
+
this.#updateComputedStylesAbortController?.abort();
|
|
872
|
+
this.#updateAbortController = new AbortController();
|
|
873
|
+
const signal = this.#updateAbortController.signal;
|
|
874
|
+
const matchedStyles = await this.fetchMatchedCascade();
|
|
875
|
+
const nodeId = this.node()?.id;
|
|
876
|
+
const parentNodeId = matchedStyles?.getParentLayoutNodeId();
|
|
877
|
+
|
|
878
|
+
const [computedStyles, parentsComputedStyles] =
|
|
879
|
+
await Promise.all([this.fetchComputedStylesFor(nodeId), this.fetchComputedStylesFor(parentNodeId)]);
|
|
880
|
+
|
|
881
|
+
if (signal.aborted) {
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
for (const section of this.allSections()) {
|
|
886
|
+
section.setComputedStyles(computedStyles);
|
|
887
|
+
section.setParentsComputedStyles(parentsComputedStyles);
|
|
888
|
+
section.updateAuthoringHint();
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
|
|
864
892
|
focusedSectionIndex(): number {
|
|
865
893
|
let index = 0;
|
|
866
894
|
for (const block of this.sectionBlocks) {
|
|
@@ -903,9 +931,6 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
|
|
|
903
931
|
|
|
904
932
|
this.linkifier.reset();
|
|
905
933
|
const prevSections = this.sectionBlocks.map(block => block.sections).flat();
|
|
906
|
-
for (const section of prevSections) {
|
|
907
|
-
section.dispose();
|
|
908
|
-
}
|
|
909
934
|
this.sectionBlocks = [];
|
|
910
935
|
|
|
911
936
|
const node = this.node();
|
|
@@ -6,9 +6,11 @@ import * as Common from '../../core/common/common.js';
|
|
|
6
6
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
7
7
|
import * as Platform from '../../core/platform/platform.js';
|
|
8
8
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
9
|
+
import * as CrUXManager from '../../models/crux-manager/crux-manager.js';
|
|
9
10
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
10
11
|
import * as Lit from '../../ui/lit/lit.js';
|
|
11
12
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
13
|
+
import * as PanelsCommon from '../common/common.js';
|
|
12
14
|
|
|
13
15
|
import {ThrottlingManager} from './ThrottlingManager.js';
|
|
14
16
|
import type {NetworkThrottlingConditionsGroup} from './ThrottlingPresets.js';
|
|
@@ -185,6 +187,18 @@ export class NetworkThrottlingSelect extends Common.ObjectWrapper.ObjectWrapper<
|
|
|
185
187
|
SDK.NetworkManager.MultitargetNetworkManager.Events.CONDITIONS_CHANGED, () => {
|
|
186
188
|
select.currentConditions = SDK.NetworkManager.MultitargetNetworkManager.instance().networkConditions();
|
|
187
189
|
});
|
|
190
|
+
|
|
191
|
+
// Subscribe to CrUX field data changes to show recommended throttling
|
|
192
|
+
// presets based on real-user RTT data.
|
|
193
|
+
const cruxManager = CrUXManager.CrUXManager.instance();
|
|
194
|
+
const updateRecommendation = (): void => {
|
|
195
|
+
const roundTripTimeMetricData = cruxManager.getSelectedFieldMetricData('round_trip_time');
|
|
196
|
+
select.recommendedConditions =
|
|
197
|
+
PanelsCommon.ThrottlingUtils.getRecommendedNetworkConditions(roundTripTimeMetricData);
|
|
198
|
+
};
|
|
199
|
+
cruxManager.addEventListener(CrUXManager.Events.FIELD_DATA_CHANGED, updateRecommendation);
|
|
200
|
+
updateRecommendation();
|
|
201
|
+
|
|
188
202
|
return select;
|
|
189
203
|
}
|
|
190
204
|
|
|
@@ -298,9 +298,6 @@ export class ProfileView extends UI.View.SimpleView implements UI.SearchableView
|
|
|
298
298
|
if (!this.profileDataGridTree) {
|
|
299
299
|
return;
|
|
300
300
|
}
|
|
301
|
-
const selectedProfileNode =
|
|
302
|
-
this.dataGrid.selectedNode ? (this.dataGrid.selectedNode as ProfileDataGridNode).profileNode : null;
|
|
303
|
-
|
|
304
301
|
this.dataGrid.rootNode().removeChildren();
|
|
305
302
|
|
|
306
303
|
const children = this.profileDataGridTree.children;
|
|
@@ -309,12 +306,6 @@ export class ProfileView extends UI.View.SimpleView implements UI.SearchableView
|
|
|
309
306
|
for (let index = 0; index < count; ++index) {
|
|
310
307
|
this.dataGrid.rootNode().appendChild(children[index]);
|
|
311
308
|
}
|
|
312
|
-
|
|
313
|
-
if (selectedProfileNode) {
|
|
314
|
-
// TODO(crbug.com/1011811): Cleanup the added `selected` property to this SDK class.
|
|
315
|
-
// @ts-expect-error
|
|
316
|
-
selectedProfileNode.selected = true;
|
|
317
|
-
}
|
|
318
309
|
}
|
|
319
310
|
|
|
320
311
|
refreshVisibleData(): void {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
background-color: var(--sys-color-tonal-container);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
.keybinds-list-item.keybinds-editing {
|
|
38
|
+
.keybinds-list-item-wrapper:has(.keybinds-list-item.keybinds-editing) {
|
|
39
39
|
background-color: var(--sys-color-neutral-container);
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -168,31 +168,30 @@ button.text-button {
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
@media (forced-colors: active) {
|
|
171
|
-
|
|
171
|
+
.keybinds-list-item.keybinds-editing .keybinds-shortcut {
|
|
172
|
+
& devtools-button {
|
|
173
|
+
--sys-color-primary: buttonFace;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.keybinds-list-text input {
|
|
178
|
+
color: buttonText;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/* Keyboard focus / hover on wrapper element (shortcut items) */
|
|
172
182
|
.keybinds-list-item-wrapper {
|
|
183
|
+
&:has(.keybinds-list-item:hover),
|
|
184
|
+
&:has(.keybinds-list-item:not(.keybinds-editing)):focus-within,
|
|
173
185
|
&:focus,
|
|
174
186
|
&:focus-visible {
|
|
175
|
-
background-color: Highlight
|
|
187
|
+
background-color: Highlight;
|
|
176
188
|
forced-color-adjust: none;
|
|
177
189
|
|
|
190
|
+
--icon-default: HighlightText;
|
|
191
|
+
|
|
178
192
|
& .keybinds-list-text,
|
|
179
193
|
& .keybinds-action-name {
|
|
180
|
-
color: HighlightText
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
& .keybinds-key {
|
|
184
|
-
background: HighlightText;
|
|
185
|
-
color: Highlight;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/* Hover state (shortcut items) */
|
|
190
|
-
&:has(.keybinds-list-item:hover) {
|
|
191
|
-
background-color: Highlight !important; /* stylelint-disable-line declaration-no-important */
|
|
192
|
-
forced-color-adjust: none;
|
|
193
|
-
|
|
194
|
-
& .keybinds-list-text {
|
|
195
|
-
color: HighlightText !important; /* stylelint-disable-line declaration-no-important */
|
|
194
|
+
color: HighlightText;
|
|
196
195
|
}
|
|
197
196
|
|
|
198
197
|
& .keybinds-key {
|
|
@@ -203,23 +202,18 @@ button.text-button {
|
|
|
203
202
|
}
|
|
204
203
|
|
|
205
204
|
/* Editing state */
|
|
206
|
-
.keybinds-list-item.keybinds-editing {
|
|
207
|
-
background-color: Highlight
|
|
205
|
+
.keybinds-list-item-wrapper:has(.keybinds-list-item.keybinds-editing) {
|
|
206
|
+
background-color: Highlight;
|
|
208
207
|
forced-color-adjust: none;
|
|
209
208
|
|
|
209
|
+
--icon-default: HighlightText;
|
|
210
|
+
|
|
210
211
|
& .keybinds-list-text {
|
|
211
|
-
color: HighlightText
|
|
212
|
+
color: HighlightText;
|
|
212
213
|
}
|
|
213
|
-
}
|
|
214
214
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
&:hover,
|
|
218
|
-
&:focus,
|
|
219
|
-
&:focus-visible {
|
|
220
|
-
background-color: Highlight !important; /* stylelint-disable-line declaration-no-important */
|
|
221
|
-
color: HighlightText !important; /* stylelint-disable-line declaration-no-important */
|
|
222
|
-
forced-color-adjust: none;
|
|
215
|
+
& .keybinds-error {
|
|
216
|
+
color: highlightText;
|
|
223
217
|
}
|
|
224
218
|
}
|
|
225
219
|
}
|
|
@@ -257,6 +257,8 @@ export class ThirdPartyTreeViewWidget extends TimelineTreeView.TimelineTreeView
|
|
|
257
257
|
export class ThirdPartyTreeElement extends UI.Widget.WidgetElement<UI.Widget.Widget> {
|
|
258
258
|
#treeView?: ThirdPartyTreeViewWidget;
|
|
259
259
|
|
|
260
|
+
static readonly observedAttributes = ['max-rows'];
|
|
261
|
+
|
|
260
262
|
set treeView(treeView: ThirdPartyTreeViewWidget) {
|
|
261
263
|
this.#treeView = treeView;
|
|
262
264
|
}
|
|
@@ -266,6 +268,12 @@ export class ThirdPartyTreeElement extends UI.Widget.WidgetElement<UI.Widget.Wid
|
|
|
266
268
|
this.style.display = 'contents';
|
|
267
269
|
}
|
|
268
270
|
|
|
271
|
+
attributeChangedCallback(name: string, _oldValue: string|null, newValue: string|null): void {
|
|
272
|
+
if (name === 'max-rows' && newValue) {
|
|
273
|
+
this.style.setProperty('--max-rows', newValue);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
269
277
|
override createWidget(): UI.Widget.Widget {
|
|
270
278
|
const containerWidget = new UI.Widget.Widget(this);
|
|
271
279
|
containerWidget.contentElement.style.display = 'contents';
|
|
@@ -62,6 +62,7 @@ import * as SettingsUI from '../../ui/legacy/components/settings_ui/settings_ui.
|
|
|
62
62
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
63
63
|
import * as ThemeSupport from '../../ui/legacy/theme_support/theme_support.js';
|
|
64
64
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
65
|
+
import * as PanelsCommon from '../common/common.js';
|
|
65
66
|
import * as MobileThrottling from '../mobile_throttling/mobile_throttling.js';
|
|
66
67
|
|
|
67
68
|
import {ActiveFilters} from './ActiveFilters.js';
|
|
@@ -93,7 +94,7 @@ import {TimelineUIUtils} from './TimelineUIUtils.js';
|
|
|
93
94
|
import {createHiddenTracksOverlay} from './TrackConfigBanner.js';
|
|
94
95
|
import {UIDevtoolsController} from './UIDevtoolsController.js';
|
|
95
96
|
import {UIDevtoolsUtils} from './UIDevtoolsUtils.js';
|
|
96
|
-
import * as Utils from './utils/utils.js';
|
|
97
|
+
import type * as Utils from './utils/utils.js';
|
|
97
98
|
|
|
98
99
|
const UIStrings = {
|
|
99
100
|
/**
|
|
@@ -800,7 +801,7 @@ export class TimelinePanel extends Common.ObjectWrapper.eventMixin<EventTypes, t
|
|
|
800
801
|
}
|
|
801
802
|
|
|
802
803
|
#onFieldDataChanged(): void {
|
|
803
|
-
const recs =
|
|
804
|
+
const recs = PanelsCommon.ThrottlingUtils.getThrottlingRecommendations();
|
|
804
805
|
this.cpuThrottlingSelect?.updateRecommendedOption(recs.cpuOption);
|
|
805
806
|
if (this.networkThrottlingSelect) {
|
|
806
807
|
this.networkThrottlingSelect.recommendedConditions = recs.networkConditions;
|
|
@@ -3281,6 +3282,17 @@ export class CoreVitalsRevealer implements Common.Revealer.Revealer<Utils.Helper
|
|
|
3281
3282
|
}
|
|
3282
3283
|
}
|
|
3283
3284
|
|
|
3285
|
+
export class TimeRangeRevealer implements Common.Revealer.Revealer<Utils.Helpers.RevealableTimeRange> {
|
|
3286
|
+
async reveal(revealable: Utils.Helpers.RevealableTimeRange): Promise<void> {
|
|
3287
|
+
await UI.ViewManager.ViewManager.instance().showView('timeline');
|
|
3288
|
+
const panel = TimelinePanel.instance();
|
|
3289
|
+
TraceBounds.TraceBounds.BoundsManager.instance().setTimelineVisibleWindow(
|
|
3290
|
+
revealable.bounds, {ignoreMiniMapBounds: true, shouldAnimate: true});
|
|
3291
|
+
panel.select(null);
|
|
3292
|
+
panel.getFlameChart().selectDetailsViewTab(Tab.Details, null);
|
|
3293
|
+
}
|
|
3294
|
+
}
|
|
3295
|
+
|
|
3284
3296
|
export class ActionDelegate implements UI.ActionRegistration.ActionDelegate {
|
|
3285
3297
|
handleAction(context: UI.Context.Context, actionId: string): boolean {
|
|
3286
3298
|
const panel = context.flavor(TimelinePanel);
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
/* eslint-disable @devtools/no-lit-render-outside-of-view */
|
|
5
5
|
|
|
6
6
|
import '../../../ui/kit/kit.js';
|
|
7
|
-
import './OriginMap.js';
|
|
8
7
|
|
|
9
8
|
import * as i18n from '../../../core/i18n/i18n.js';
|
|
10
9
|
import * as CrUXManager from '../../../models/crux-manager/crux-manager.js';
|
|
@@ -13,11 +12,12 @@ import * as Dialogs from '../../../ui/components/dialogs/dialogs.js';
|
|
|
13
12
|
import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
|
|
14
13
|
import * as Input from '../../../ui/components/input/input.js';
|
|
15
14
|
import * as uiI18n from '../../../ui/i18n/i18n.js';
|
|
15
|
+
import * as UI from '../../../ui/legacy/legacy.js';
|
|
16
16
|
import * as Lit from '../../../ui/lit/lit.js';
|
|
17
17
|
import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
|
|
18
18
|
|
|
19
19
|
import fieldSettingsDialogStyles from './fieldSettingsDialog.css.js';
|
|
20
|
-
import
|
|
20
|
+
import {OriginMap} from './OriginMap.js';
|
|
21
21
|
|
|
22
22
|
const UIStrings = {
|
|
23
23
|
/**
|
|
@@ -95,6 +95,7 @@ const str_ = i18n.i18n.registerUIStrings('panels/timeline/components/FieldSettin
|
|
|
95
95
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
96
96
|
|
|
97
97
|
const {html, nothing, Directives: {ifDefined}} = Lit;
|
|
98
|
+
const {widget, widgetRef} = UI.Widget;
|
|
98
99
|
|
|
99
100
|
export class ShowDialog extends Event {
|
|
100
101
|
static readonly eventName = 'showdialog';
|
|
@@ -309,13 +310,8 @@ export class FieldSettingsDialog extends HTMLElement {
|
|
|
309
310
|
// clang-format off
|
|
310
311
|
return html`
|
|
311
312
|
<div class="origin-mapping-description">${i18nString(UIStrings.mapDevelopmentOrigins)}</div>
|
|
312
|
-
<devtools-
|
|
313
|
-
|
|
314
|
-
if (el instanceof HTMLElement) {
|
|
315
|
-
this.#originMap = el as OriginMap;
|
|
316
|
-
}
|
|
317
|
-
})}
|
|
318
|
-
></devtools-origin-map>
|
|
313
|
+
<devtools-widget ${widget(OriginMap)} ${widgetRef(OriginMap, el => { this.#originMap = el; })}>
|
|
314
|
+
</devtools-widget>
|
|
319
315
|
<div class="origin-mapping-button-section">
|
|
320
316
|
<devtools-button
|
|
321
317
|
@click=${() => this.#originMap?.startCreation()}
|
|
@@ -31,7 +31,6 @@ import * as UI from '../../../ui/legacy/legacy.js';
|
|
|
31
31
|
import * as Lit from '../../../ui/lit/lit.js';
|
|
32
32
|
import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
|
|
33
33
|
import * as PanelsCommon from '../../common/common.js';
|
|
34
|
-
import * as Utils from '../utils/utils.js';
|
|
35
34
|
|
|
36
35
|
import {CPUThrottlingSelector} from './CPUThrottlingSelector.js';
|
|
37
36
|
import {md} from './insights/Helpers.js';
|
|
@@ -636,7 +635,7 @@ export class LiveMetricsView extends LegacyWrapper.LegacyWrapper.WrappableCompon
|
|
|
636
635
|
networkRecEl.classList.add('environment-rec');
|
|
637
636
|
networkRecEl.textContent = this.#getNetworkRecTitle() || i18nString(UIStrings.notEnoughData);
|
|
638
637
|
|
|
639
|
-
const recs =
|
|
638
|
+
const recs = PanelsCommon.ThrottlingUtils.getThrottlingRecommendations();
|
|
640
639
|
|
|
641
640
|
// clang-format off
|
|
642
641
|
return html`
|