chrome-devtools-frontend 1.0.1681498 → 1.0.1682249

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/eslint.config.mjs +8 -3
  2. package/front_end/core/sdk/ConsoleModel.ts +1 -1
  3. package/front_end/core/sdk/PreloadingModel.ts +44 -22
  4. package/front_end/core/sdk/RemoteObject.ts +4 -1
  5. package/front_end/core/sdk/RuntimeModel.ts +5 -5
  6. package/front_end/core/sdk/sdk.ts +2 -0
  7. package/front_end/entrypoints/formatter_worker/FormatterWorker.ts +1 -1
  8. package/front_end/entrypoints/inspector_main/InspectorMain.ts +3 -1
  9. package/front_end/entrypoints/inspector_main/inspector_main-meta.ts +1 -5
  10. package/front_end/entrypoints/main/MainImpl.ts +9 -10
  11. package/front_end/entrypoints/shell/shell.ts +0 -2
  12. package/front_end/entrypoints/trace_app/trace_app.ts +0 -2
  13. package/front_end/generated/InspectorBackendCommands.ts +2 -0
  14. package/front_end/generated/protocol-mapping.d.ts +16 -0
  15. package/front_end/generated/protocol-proxy-api.d.ts +12 -0
  16. package/front_end/generated/protocol.ts +12 -0
  17. package/front_end/models/ai_assistance/ExtensionScope.ts +11 -12
  18. package/front_end/models/ai_assistance/agents/AiAgent.ts +1 -1
  19. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +2 -1
  20. package/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt +1 -1
  21. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +2 -1
  22. package/front_end/models/ai_assistance/contexts/PerformanceTraceContext.ts +2 -1
  23. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt +8 -8
  24. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +8 -8
  25. package/front_end/models/bindings/DebuggerLanguagePlugins.ts +1 -0
  26. package/front_end/models/formatter/ScriptFormatter.ts +1 -0
  27. package/front_end/models/javascript_metadata/NativeFunctions.js +5 -1
  28. package/front_end/models/live-metrics/web-vitals-injected/spec/spec.ts +4 -4
  29. package/front_end/models/logs/NetworkLog.ts +8 -1
  30. package/front_end/models/persistence/AutomaticFileSystemWorkspaceBinding.ts +4 -2
  31. package/front_end/models/stack_trace/StackTraceImpl.ts +1 -0
  32. package/front_end/models/trace/Name.ts +5 -5
  33. package/front_end/models/trace/Styles.ts +115 -115
  34. package/front_end/models/trace/extras/TraceTree.ts +2 -1
  35. package/front_end/models/trace/helpers/Network.ts +4 -1
  36. package/front_end/models/trace/insights/CLSCulprits.ts +4 -2
  37. package/front_end/models/trace/insights/CharacterSet.ts +3 -3
  38. package/front_end/models/trace/insights/DOMSize.ts +1 -1
  39. package/front_end/models/trace/insights/DuplicatedJavaScript.ts +6 -2
  40. package/front_end/models/trace/insights/FontDisplay.ts +9 -3
  41. package/front_end/models/trace/insights/ForcedReflow.ts +4 -4
  42. package/front_end/models/trace/insights/INPBreakdown.ts +3 -4
  43. package/front_end/models/trace/insights/ImageDelivery.ts +2 -2
  44. package/front_end/models/trace/insights/LCPBreakdown.ts +1 -1
  45. package/front_end/models/trace/insights/LCPDiscovery.ts +5 -5
  46. package/front_end/models/trace/insights/LegacyJavaScript.ts +7 -3
  47. package/front_end/models/trace/insights/ModernHTTP.ts +3 -3
  48. package/front_end/models/trace/insights/NetworkDependencyTree.ts +13 -9
  49. package/front_end/models/trace/insights/RenderBlocking.ts +1 -1
  50. package/front_end/models/trace/insights/SlowCSSSelector.ts +29 -25
  51. package/front_end/models/trace/insights/ThirdParties.ts +13 -5
  52. package/front_end/models/trace/insights/Viewport.ts +4 -2
  53. package/front_end/models/workspace/IgnoreListManager.ts +53 -17
  54. package/front_end/panels/accessibility/ARIAAttributesView.ts +11 -2
  55. package/front_end/panels/ai_assistance/components/ChatMessage.ts +67 -53
  56. package/front_end/panels/ai_assistance/components/ChatView.ts +2 -2
  57. package/front_end/panels/ai_assistance/components/StylingAgentMarkdownRenderer.ts +2 -2
  58. package/front_end/panels/ai_assistance/components/WalkthroughView.ts +5 -5
  59. package/front_end/panels/animation/AnimationTimeline.ts +2 -0
  60. package/front_end/panels/application/preloading/PreloadingView.ts +9 -3
  61. package/front_end/panels/application/preloading/components/components.ts +2 -0
  62. package/front_end/panels/browser_debugger/ObjectEventListenersSidebarPane.ts +10 -11
  63. package/front_end/panels/changes/CombinedDiffView.ts +1 -1
  64. package/front_end/panels/common/ExtensionServer.ts +9 -10
  65. package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +9 -4
  66. package/front_end/panels/elements/ElementStatePaneWidget.ts +3 -0
  67. package/front_end/panels/elements/ElementsTreeElement.ts +7 -1
  68. package/front_end/panels/elements/EventListenersWidget.ts +10 -11
  69. package/front_end/panels/issues/IssueView.ts +5 -6
  70. package/front_end/panels/linear_memory_inspector/components/LinearMemoryViewer.ts +1 -1
  71. package/front_end/panels/media/PlayerPropertiesView.ts +309 -416
  72. package/front_end/panels/media/playerPropertiesView.css +1 -1
  73. package/front_end/panels/network/NetworkPanel.ts +2 -1
  74. package/front_end/panels/network/components/ResponseHeaderSection.ts +1 -2
  75. package/front_end/panels/network/network-meta.ts +6 -0
  76. package/front_end/panels/performance_monitor/PerformanceMonitor.ts +2 -1
  77. package/front_end/panels/recorder/RecordingView.ts +89 -73
  78. package/front_end/panels/recorder/ReplaySection.ts +59 -40
  79. package/front_end/panels/recorder/injected/injected.ts +4 -0
  80. package/front_end/panels/security/SecurityPanel.ts +5 -6
  81. package/front_end/panels/security/SecurityPanelSidebar.ts +244 -204
  82. package/front_end/panels/security/security.ts +0 -4
  83. package/front_end/panels/settings/EditFileSystemView.ts +8 -7
  84. package/front_end/panels/settings/FrameworkIgnoreListSettingsTab.ts +20 -14
  85. package/front_end/panels/snippets/ScriptSnippetFileSystem.ts +10 -11
  86. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +3 -3
  87. package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +5 -5
  88. package/front_end/panels/timeline/components/CWVMetrics.ts +1 -2
  89. package/front_end/panels/timeline/components/IgnoreListSetting.ts +5 -5
  90. package/front_end/panels/timeline/components/LayoutShiftDetails.ts +2 -3
  91. package/front_end/panels/timeline/components/LiveMetricsView.ts +2 -2
  92. package/front_end/panels/timeline/components/Sidebar.ts +3 -3
  93. package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +1 -2
  94. package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +3 -1
  95. package/front_end/panels/timeline/components/insights/CLSCulprits.ts +1 -2
  96. package/front_end/panels/timeline/components/insights/Cache.ts +1 -2
  97. package/front_end/panels/timeline/components/insights/CharacterSet.ts +1 -2
  98. package/front_end/panels/timeline/components/insights/DOMSize.ts +1 -2
  99. package/front_end/panels/timeline/components/insights/DocumentLatency.ts +2 -2
  100. package/front_end/panels/timeline/components/insights/DuplicatedJavaScript.ts +2 -2
  101. package/front_end/panels/timeline/components/insights/FontDisplay.ts +1 -2
  102. package/front_end/panels/timeline/components/insights/ForcedReflow.ts +1 -2
  103. package/front_end/panels/timeline/components/insights/INPBreakdown.ts +1 -2
  104. package/front_end/panels/timeline/components/insights/ImageDelivery.ts +1 -2
  105. package/front_end/panels/timeline/components/insights/LCPBreakdown.ts +13 -13
  106. package/front_end/panels/timeline/components/insights/LCPDiscovery.ts +1 -2
  107. package/front_end/panels/timeline/components/insights/LegacyJavaScript.ts +4 -4
  108. package/front_end/panels/timeline/components/insights/ModernHTTP.ts +1 -2
  109. package/front_end/panels/timeline/components/insights/NetworkDependencyTree.ts +10 -8
  110. package/front_end/panels/timeline/components/insights/RenderBlocking.ts +2 -2
  111. package/front_end/panels/timeline/components/insights/SidebarInsight.ts +3 -1
  112. package/front_end/panels/timeline/components/insights/SlowCSSSelector.ts +2 -2
  113. package/front_end/panels/timeline/components/insights/ThirdParties.ts +1 -2
  114. package/front_end/panels/timeline/components/insights/Viewport.ts +1 -2
  115. package/front_end/panels/timeline/overlays/OverlaysImpl.ts +1 -2
  116. package/front_end/panels/timeline/timeline.ts +0 -2
  117. package/front_end/panels/web_audio/WebAudioView.ts +7 -7
  118. package/front_end/panels/webauthn/WebauthnPane.ts +9 -9
  119. package/front_end/third_party/chromium/README.chromium +1 -1
  120. package/front_end/ui/components/diff_view/DiffView.ts +2 -1
  121. package/front_end/ui/components/report_view/ReportView.docs.ts +2 -2
  122. package/front_end/ui/components/text_editor/javascript.ts +12 -13
  123. package/front_end/ui/legacy/GlassPane.ts +38 -14
  124. package/front_end/ui/legacy/Treeoutline.ts +14 -3
  125. package/front_end/ui/legacy/components/object_ui/CustomPreviewComponent.ts +1 -1
  126. package/front_end/ui/legacy/components/object_ui/JavaScriptREPL.ts +1 -1
  127. package/front_end/ui/legacy/components/object_ui/ObjectPopoverHelper.ts +1 -1
  128. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +21 -30
  129. package/front_end/ui/legacy/components/object_ui/RemoteObjectPreviewFormatter.ts +3 -8
  130. package/front_end/ui/legacy/components/utils/ImagePreview.ts +15 -16
  131. package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +4 -4
  132. package/front_end/ui/legacy/components/utils/Linkifier.ts +8 -10
  133. package/front_end/ui/settings/InspectorMainSettings.ts +12 -0
  134. package/front_end/ui/settings/settings.ts +2 -0
  135. package/front_end/ui/visual_logging/KnownContextValues.ts +21 -0
  136. package/mcp/mcp.ts +0 -6
  137. package/package.json +1 -1
  138. package/front_end/models/logs/logs-meta.ts +0 -24
  139. package/front_end/models/workspace/workspace-meta.ts +0 -40
  140. package/front_end/panels/security/OriginTreeElement.ts +0 -60
  141. package/front_end/panels/security/SecurityPanelSidebarTreeElement.ts +0 -30
@@ -1,24 +1,22 @@
1
1
  // Copyright 2024 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 @devtools/no-imperative-dom-api */
5
4
 
6
5
  import * as Common from '../../core/common/common.js';
7
6
  import * as i18n from '../../core/i18n/i18n.js';
8
- import * as Platform from '../../core/platform/platform.js';
7
+ import type * as Platform from '../../core/platform/platform.js';
9
8
  import * as Protocol from '../../generated/protocol.js';
10
9
  import type {Icon} from '../../ui/kit/kit.js';
11
10
  import * as UI from '../../ui/legacy/legacy.js';
11
+ import {html, nothing, render, type TemplateResult} from '../../ui/lit/lit.js';
12
12
 
13
13
  import lockIconStyles from './lockIcon.css.js';
14
- import {OriginTreeElement} from './OriginTreeElement.js';
15
14
  import {
16
15
  createHighlightedUrl,
17
16
  getSecurityStateIconForDetailedView,
18
17
  getSecurityStateIconForOverview,
19
18
  OriginGroup,
20
19
  } from './SecurityPanel.js';
21
- import type {SecurityPanelSidebarTreeElement} from './SecurityPanelSidebarTreeElement.js';
22
20
  import sidebarStyles from './sidebar.css.js';
23
21
 
24
22
  const UIStrings = {
@@ -55,247 +53,289 @@ const UIStrings = {
55
53
  const str_ = i18n.i18n.registerUIStrings('panels/security/SecurityPanelSidebar.ts', UIStrings);
56
54
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
57
55
 
58
- export class SecurityPanelSidebar extends UI.Widget.VBox {
59
- readonly #securitySidebarLastItemSetting: Common.Settings.Setting<string>;
60
- readonly sidebarTree: UI.TreeOutline.TreeOutlineInShadow;
61
- readonly #originGroupTitles: Map<OriginGroup, {title: string, icon?: Icon}>;
62
- #originGroups: Map<OriginGroup, UI.TreeOutline.TreeElement>;
63
- securityOverviewElement: OriginTreeElement;
64
- readonly #elementsByOrigin: Map<string, OriginTreeElement>;
65
- readonly #mainViewReloadMessage: UI.TreeOutline.TreeElement;
66
- #mainOrigin: string|null;
67
-
68
- constructor(element?: HTMLElement) {
69
- super(element);
70
-
71
- this.#securitySidebarLastItemSetting =
72
- Common.Settings.Settings.instance().createSetting('security-last-selected-element-path', '');
73
- this.#mainOrigin = null;
74
-
75
- this.sidebarTree = new UI.TreeOutline.TreeOutlineInShadow(UI.TreeOutline.TreeVariant.NAVIGATION_TREE);
76
- this.sidebarTree.registerRequiredCSS(lockIconStyles, sidebarStyles);
77
- this.sidebarTree.element.classList.add('security-sidebar');
78
- this.contentElement.appendChild(this.sidebarTree.element);
79
-
80
- const securitySectionTitle = i18nString(UIStrings.security);
81
- const securityTreeSection = this.#addSidebarSection(securitySectionTitle, 'security');
82
-
83
- this.securityOverviewElement =
84
- new OriginTreeElement('security-main-view-sidebar-tree-item', this.#renderTreeElement);
85
- this.securityOverviewElement.tooltip = i18nString(UIStrings.overview);
86
- securityTreeSection.appendChild(this.securityOverviewElement);
87
-
88
- this.#originGroupTitles = new Map([
89
- [OriginGroup.MainOrigin, {title: i18nString(UIStrings.mainOrigin)}],
90
- [
91
- OriginGroup.NonSecure,
92
- {
93
- title: i18nString(UIStrings.nonsecureOrigins),
94
- icon: getSecurityStateIconForDetailedView(
95
- Protocol.Security.SecurityState.Insecure,
96
- `lock-icon lock-icon-${Protocol.Security.SecurityState.Insecure}`),
97
- },
98
- ],
99
- [
100
- OriginGroup.Secure,
101
- {
102
- title: i18nString(UIStrings.secureOrigins),
103
- icon: getSecurityStateIconForDetailedView(
104
- Protocol.Security.SecurityState.Secure, `lock-icon lock-icon-${Protocol.Security.SecurityState.Secure}`),
105
- },
106
- ],
107
- [
108
- OriginGroup.Unknown,
109
- {
110
- title: i18nString(UIStrings.unknownCanceled),
111
- icon: getSecurityStateIconForDetailedView(
112
- Protocol.Security.SecurityState.Unknown,
113
- `lock-icon lock-icon-${Protocol.Security.SecurityState.Unknown}`),
114
- },
115
- ],
116
- ]);
117
-
118
- this.#originGroups = new Map();
119
- for (const group of Object.values(OriginGroup)) {
120
- const element = this.#createOriginGroupElement(
121
- this.#originGroupTitles.get(group)?.title as string, this.#originGroupTitles.get(group)?.icon);
122
- this.#originGroups.set(group, element);
123
- securityTreeSection.appendChild(element);
124
- }
125
-
126
- this.#mainViewReloadMessage = new UI.TreeOutline.TreeElement(i18nString(UIStrings.reloadToViewDetails));
127
- this.#mainViewReloadMessage.selectable = false;
128
- this.#mainViewReloadMessage.listItemElement.classList.add('security-main-view-reload-message');
129
- const treeElement = this.#originGroups.get(OriginGroup.MainOrigin);
130
- (treeElement as UI.TreeOutline.TreeElement).appendChild(this.#mainViewReloadMessage);
56
+ export interface ViewInput {
57
+ mainOrigin: string|null;
58
+ origins: Map<Platform.DevToolsPath.UrlString, Protocol.Security.SecurityState>;
59
+ originsHidden: boolean;
60
+ showOriginsUnconditionally: boolean;
61
+ overviewSecurityState: Protocol.Security.SecurityState;
62
+ selectedElementId: string;
63
+ }
131
64
 
132
- this.#clearOriginGroups();
65
+ export interface ViewOutput {
66
+ onElementSelected: (id: string) => void;
67
+ onShowOrigin: (origin: Platform.DevToolsPath.UrlString|null) => void;
68
+ }
133
69
 
134
- this.#elementsByOrigin = new Map();
70
+ export type View = (input: ViewInput, output: ViewOutput, target: HTMLElement) => void;
71
+
72
+ export const DEFAULT_VIEW: View = (input, output, target) => {
73
+ const renderIcon = (icon: Icon): TemplateResult => html`${icon}`;
74
+
75
+ const renderOrigin =
76
+ (origin: Platform.DevToolsPath.UrlString, state: Protocol.Security.SecurityState): TemplateResult => {
77
+ const icon = getSecurityStateIconForDetailedView(state, `security-property security-property-${state}`);
78
+ const selected = input.selectedElementId === origin;
79
+ // clang-format off
80
+ return html`
81
+ <li role="treeitem"
82
+ class="security-sidebar-tree-item"
83
+ title=${origin}
84
+ ?selected=${selected}
85
+ @click=${() => {
86
+ output.onElementSelected(origin);
87
+ output.onShowOrigin(origin);
88
+ }}>
89
+ ${renderIcon(icon)}
90
+ ${createHighlightedUrl(origin, state)}
91
+ </li>
92
+ `;
93
+ // clang-format on
94
+ };
95
+
96
+ const getGroupTitle = (group: OriginGroup): string => {
97
+ switch (group) {
98
+ case OriginGroup.MainOrigin:
99
+ return i18nString(UIStrings.mainOrigin);
100
+ case OriginGroup.NonSecure:
101
+ return i18nString(UIStrings.nonsecureOrigins);
102
+ case OriginGroup.Secure:
103
+ return i18nString(UIStrings.secureOrigins);
104
+ case OriginGroup.Unknown:
105
+ return i18nString(UIStrings.unknownCanceled);
106
+ }
107
+ };
108
+
109
+ const getGroupIcon = (group: OriginGroup, mainOriginState = Protocol.Security.SecurityState.Unknown): Icon|null => {
110
+ switch (group) {
111
+ case OriginGroup.MainOrigin:
112
+ return getSecurityStateIconForOverview(mainOriginState, `lock-icon lock-icon-${mainOriginState}`);
113
+ case OriginGroup.NonSecure:
114
+ return getSecurityStateIconForDetailedView(Protocol.Security.SecurityState.Insecure,
115
+ `lock-icon lock-icon-${Protocol.Security.SecurityState.Insecure}`);
116
+ case OriginGroup.Secure:
117
+ return getSecurityStateIconForDetailedView(Protocol.Security.SecurityState.Secure,
118
+ `lock-icon lock-icon-${Protocol.Security.SecurityState.Secure}`);
119
+ case OriginGroup.Unknown:
120
+ return getSecurityStateIconForDetailedView(Protocol.Security.SecurityState.Unknown,
121
+ `lock-icon lock-icon-${Protocol.Security.SecurityState.Unknown}`);
122
+ }
123
+ };
135
124
 
136
- this.element.addEventListener('update-sidebar-selection', (event: Event) => {
137
- const id: string = (event as CustomEvent).detail.id;
138
- this.#securitySidebarLastItemSetting.set(id);
139
- });
140
- this.showLastSelectedElement();
125
+ const originsByGroup =
126
+ new Map<OriginGroup, Array<{origin: Platform.DevToolsPath.UrlString, state: Protocol.Security.SecurityState}>>();
127
+ for (const group of Object.values(OriginGroup)) {
128
+ originsByGroup.set(group, []);
141
129
  }
142
130
 
143
- // Used in web tests
144
- elementsByOrigin(): Map<string, OriginTreeElement> {
145
- return this.#elementsByOrigin;
131
+ let mainOriginState = Protocol.Security.SecurityState.Unknown;
132
+ const overviewIcon = getSecurityStateIconForOverview(input.overviewSecurityState,
133
+ 'lock-icon lock-icon-' + input.overviewSecurityState);
134
+ for (const [origin, state] of input.origins) {
135
+ if (origin === input.mainOrigin) {
136
+ originsByGroup.get(OriginGroup.MainOrigin)?.push({origin, state});
137
+ mainOriginState = state;
138
+ } else {
139
+ switch (state) {
140
+ case Protocol.Security.SecurityState.Secure:
141
+ originsByGroup.get(OriginGroup.Secure)?.push({origin, state});
142
+ break;
143
+ case Protocol.Security.SecurityState.Unknown:
144
+ originsByGroup.get(OriginGroup.Unknown)?.push({origin, state});
145
+ break;
146
+ default:
147
+ originsByGroup.get(OriginGroup.NonSecure)?.push({origin, state});
148
+ break;
149
+ }
150
+ }
146
151
  }
147
152
 
148
- showLastSelectedElement(): void {
149
- this.securityOverviewElement.select();
150
- this.securityOverviewElement.showElement();
151
- }
153
+ const renderGroup = (group: OriginGroup): TemplateResult => {
154
+ const origins = originsByGroup.get(group) || [];
155
+ const title = getGroupTitle(group);
156
+ const icon = getGroupIcon(group, mainOriginState);
157
+ const isHidden = input.originsHidden ||
158
+ (!input.showOriginsUnconditionally && group !== OriginGroup.MainOrigin && origins.length === 0);
159
+ const showReloadMessage = group === OriginGroup.MainOrigin && input.origins.size === 0;
160
+
161
+ // clang-format off
162
+ return html`
163
+ <li role="treeitem" class="security-sidebar-origins" open ?hidden=${isHidden}>
164
+ ${icon ? renderIcon(icon) : nothing}
165
+ <span class="security-sidebar-origins-title">${title}</span>
166
+ <ul role="group" aria-label=${title}>
167
+ ${showReloadMessage ? html`
168
+ <li role="treeitem" class="security-main-view-reload-message" aria-disabled="true">
169
+ ${i18nString(UIStrings.reloadToViewDetails)}
170
+ </li>
171
+ ` : nothing}
172
+ ${origins.map(o => renderOrigin(o.origin, o.state))}
173
+ </ul>
174
+ </li>
175
+ `;
176
+ // clang-format on
177
+ };
178
+
179
+ // clang-format off
180
+ render(html`
181
+ <devtools-tree class="security-sidebar" navigation-variant .template=${html`
182
+ <ul role="tree">
183
+ <li role="treeitem" class="security-group-list-item" aria-level="3" aria-label=${i18nString(UIStrings.security)}>
184
+ ${i18nString(UIStrings.security)}
185
+ <ul role="group">
186
+ <li role="treeitem"
187
+ class="security-main-view-sidebar-tree-item"
188
+ title=${i18nString(UIStrings.overview)}
189
+ ?selected=${input.selectedElementId === 'overview'}
190
+ @click=${() => {
191
+ output.onElementSelected('overview');
192
+ output.onShowOrigin(null);
193
+ }}>
194
+ ${renderIcon(overviewIcon)}
195
+ <span title=${i18nString(UIStrings.overview)}>${i18nString(UIStrings.overview)}</span>
196
+ </li>
197
+ ${Object.values(OriginGroup).map(group => renderGroup(group))}
198
+ </ul>
199
+ </li>
200
+ </ul>
201
+ `}></devtools-tree>
202
+ `, target);
203
+ // clang-format on
204
+ };
205
+
206
+ export class SecurityPanelSidebar extends UI.Widget.VBox {
207
+ readonly #securitySidebarLastItemSetting: Common.Settings.Setting<string>;
208
+ #mainOrigin: string|null = null;
209
+ #origins = new Map<Platform.DevToolsPath.UrlString, Protocol.Security.SecurityState>();
210
+ #originsHidden = false;
211
+ #showOriginsUnconditionally = false;
212
+ #overviewSecurityState = Protocol.Security.SecurityState.Unknown;
213
+ #selectedElementId = 'overview';
214
+ readonly #view: View;
215
+ #onShowOrigin?: (origin: Platform.DevToolsPath.UrlString|null) => void;
216
+
217
+ constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
218
+ super(element);
219
+ this.#view = view;
220
+ this.registerRequiredCSS(lockIconStyles, sidebarStyles);
152
221
 
153
- #addSidebarSection(title: string, jslogContext: string): UI.TreeOutline.TreeElement {
154
- const treeElement = new UI.TreeOutline.TreeElement(title, true, jslogContext);
155
- treeElement.listItemElement.classList.add('security-group-list-item');
156
- treeElement.setCollapsible(false);
157
- treeElement.selectable = false;
158
- this.sidebarTree.appendChild(treeElement);
159
- UI.ARIAUtils.markAsHeading(treeElement.listItemElement, 3);
160
- UI.ARIAUtils.setLabel(treeElement.childrenListElement, title);
161
- return treeElement;
222
+ this.#securitySidebarLastItemSetting =
223
+ Common.Settings.Settings.instance().createSetting('security-last-selected-element-path', '');
162
224
  }
163
225
 
164
- #originGroupTitle(originGroup: OriginGroup): string {
165
- return this.#originGroupTitles.get(originGroup)?.title as string;
226
+ set onShowOrigin(callback: (origin: Platform.DevToolsPath.UrlString|null) => void) {
227
+ this.#onShowOrigin = callback;
166
228
  }
167
229
 
168
- #originGroupElement(originGroup: OriginGroup): UI.TreeOutline.TreeElement {
169
- return this.#originGroups.get(originGroup) as UI.TreeOutline.TreeElement;
230
+ override wasShown(): void {
231
+ super.wasShown();
232
+ this.showLastSelectedElement();
170
233
  }
171
234
 
172
- #createOriginGroupElement(originGroupTitle: string, originGroupIcon?: Icon): UI.TreeOutline.TreeElement {
173
- const originGroup = new UI.TreeOutline.TreeElement(originGroupTitle, true);
174
- originGroup.expand();
175
- originGroup.listItemElement.classList.add('security-sidebar-origins');
176
- if (originGroupIcon) {
177
- originGroup.setLeadingIcons([originGroupIcon]);
178
- }
179
- UI.ARIAUtils.setLabel(originGroup.childrenListElement, originGroupTitle);
180
- return originGroup;
235
+ showLastSelectedElement(): void {
236
+ this.#selectedElementId = 'overview';
237
+ this.#securitySidebarLastItemSetting.set('overview');
238
+ this.requestUpdate();
239
+ this.#onShowOrigin?.(null);
181
240
  }
182
241
 
183
242
  toggleOriginsList(hidden: boolean): void {
184
- for (const element of this.#originGroups.values()) {
185
- element.hidden = hidden;
186
- }
243
+ this.#originsHidden = hidden;
244
+ this.#showOriginsUnconditionally = !hidden;
245
+ this.requestUpdate();
187
246
  }
188
247
 
189
248
  addOrigin(origin: Platform.DevToolsPath.UrlString, securityState: Protocol.Security.SecurityState): void {
190
- this.#mainViewReloadMessage.hidden = true;
191
- const originElement = new OriginTreeElement('security-sidebar-tree-item', this.#renderTreeElement, origin);
192
- originElement.tooltip = origin;
193
- this.#elementsByOrigin.set(origin, originElement);
194
- this.updateOrigin(origin, securityState);
249
+ this.#origins.set(origin, securityState);
250
+ this.requestUpdate();
195
251
  }
196
252
 
197
253
  setMainOrigin(origin: string): void {
198
254
  this.#mainOrigin = origin;
255
+ this.requestUpdate();
199
256
  }
200
257
 
201
258
  get mainOrigin(): string|null {
202
259
  return this.#mainOrigin;
203
260
  }
204
261
 
205
- get originGroups(): Map<OriginGroup, UI.TreeOutline.TreeElement> {
206
- return this.#originGroups;
262
+ updateOrigin(origin: Platform.DevToolsPath.UrlString, securityState: Protocol.Security.SecurityState): void {
263
+ this.#origins.set(origin, securityState);
264
+ this.requestUpdate();
207
265
  }
208
266
 
209
- updateOrigin(origin: string, securityState: Protocol.Security.SecurityState): void {
210
- const originElement = this.#elementsByOrigin.get(origin) as OriginTreeElement;
211
- originElement.setSecurityState(securityState);
212
-
213
- let newParent: UI.TreeOutline.TreeElement;
214
- if (origin === this.#mainOrigin) {
215
- newParent = this.#originGroups.get(OriginGroup.MainOrigin) as UI.TreeOutline.TreeElement;
216
- newParent.title = i18nString(UIStrings.mainOrigin);
217
- if (securityState === Protocol.Security.SecurityState.Secure) {
218
- newParent.setLeadingIcons(
219
- [getSecurityStateIconForOverview(securityState, `lock-icon lock-icon-${securityState}`)]);
220
- } else {
221
- newParent.setLeadingIcons(
222
- [getSecurityStateIconForOverview(securityState, `lock-icon lock-icon-${securityState}`)]);
223
- }
224
- UI.ARIAUtils.setLabel(newParent.childrenListElement, newParent.title);
225
- } else {
226
- switch (securityState) {
227
- case Protocol.Security.SecurityState.Secure:
228
- newParent = this.#originGroupElement(OriginGroup.Secure);
229
- break;
230
- case Protocol.Security.SecurityState.Unknown:
231
- newParent = this.#originGroupElement(OriginGroup.Unknown);
232
- break;
233
- default:
234
- newParent = this.#originGroupElement(OriginGroup.NonSecure);
235
- break;
236
- }
237
- }
267
+ updateOverviewSecurityState(securityState: Protocol.Security.SecurityState): void {
268
+ this.#overviewSecurityState = securityState;
269
+ this.requestUpdate();
270
+ }
238
271
 
239
- const oldParent = originElement.parent;
240
- if (oldParent !== newParent) {
241
- if (oldParent) {
242
- oldParent.removeChild(originElement);
243
- if (oldParent.childCount() === 0) {
244
- oldParent.hidden = true;
245
- }
246
- }
247
- newParent.appendChild(originElement);
248
- newParent.hidden = false;
249
- }
272
+ clearOrigins(): void {
273
+ this.#origins.clear();
274
+ this.requestUpdate();
250
275
  }
251
276
 
252
- #clearOriginGroups(): void {
253
- for (const [originGroup, originGroupElement] of this.#originGroups) {
254
- if (originGroup === OriginGroup.MainOrigin) {
255
- for (let i = originGroupElement.childCount() - 1; i > 0; i--) {
256
- originGroupElement.removeChildAtIndex(i);
257
- }
258
- originGroupElement.title = this.#originGroupTitle(OriginGroup.MainOrigin);
259
- originGroupElement.hidden = false;
260
- this.#mainViewReloadMessage.hidden = false;
261
- } else {
262
- originGroupElement.removeChildren();
263
- originGroupElement.hidden = true;
264
- }
277
+ // Used in web tests
278
+ elementsByOrigin(): Map<string, {
279
+ select: (omitFocus?: boolean, selectedByUser?: boolean) => void,
280
+ showElement: () => void,
281
+ origin: () => string,
282
+ securityState: () => Protocol.Security.SecurityState | undefined,
283
+ }> {
284
+ const map = new Map<string, {
285
+ select: (omitFocus?: boolean, selectedByUser?: boolean) => void,
286
+ showElement: () => void,
287
+ origin: () => string,
288
+ securityState: () => Protocol.Security.SecurityState | undefined,
289
+ }>();
290
+ for (const [origin, state] of this.#origins.entries()) {
291
+ const element = {
292
+ select: () => {
293
+ this.#selectedElementId = origin;
294
+ this.#securitySidebarLastItemSetting.set(origin);
295
+ this.requestUpdate();
296
+ this.#onShowOrigin?.(origin);
297
+ },
298
+ showElement: () => {
299
+ this.#onShowOrigin?.(origin);
300
+ },
301
+ origin: () => origin,
302
+ securityState: () => state,
303
+ };
304
+ map.set(origin, element);
265
305
  }
306
+ return map;
266
307
  }
267
308
 
268
- clearOrigins(): void {
269
- this.#clearOriginGroups();
270
- this.#elementsByOrigin.clear();
309
+ set selectedOrigin(origin: Platform.DevToolsPath.UrlString|null) {
310
+ this.#selectedElementId = origin ?? 'overview';
311
+ this.#securitySidebarLastItemSetting.set(this.#selectedElementId);
312
+ this.requestUpdate();
313
+ this.#onShowOrigin?.(origin);
271
314
  }
272
315
 
273
- override focus(): void {
274
- this.sidebarTree.focus();
316
+ get selectedOrigin(): string {
317
+ return this.#selectedElementId;
275
318
  }
276
319
 
277
- #renderTreeElement(element: SecurityPanelSidebarTreeElement): void {
278
- if (element instanceof OriginTreeElement) {
279
- const securityState = element.securityState() ?? Protocol.Security.SecurityState.Unknown;
280
-
281
- const isOverviewElement = element.listItemElement.classList.contains('security-main-view-sidebar-tree-item');
282
-
283
- const icon = isOverviewElement ?
284
- getSecurityStateIconForOverview(securityState, `lock-icon lock-icon-${securityState}`) :
285
- getSecurityStateIconForDetailedView(securityState, `security-property security-property-${securityState}`);
286
-
287
- element.setLeadingIcons([icon]);
288
-
289
- if (isOverviewElement) {
290
- element.title = i18nString(UIStrings.overview);
291
- } else {
292
- const elementTitle =
293
- createHighlightedUrl(element.origin() ?? Platform.DevToolsPath.EmptyUrlString, securityState);
294
- if (element.listItemElement.lastChild) {
295
- element.listItemElement.removeChild(element.listItemElement.lastChild);
296
- }
297
- element.listItemElement.appendChild(elementTitle);
298
- }
299
- }
320
+ override performUpdate(): void {
321
+ const input: ViewInput = {
322
+ mainOrigin: this.#mainOrigin,
323
+ origins: this.#origins,
324
+ originsHidden: this.#originsHidden,
325
+ showOriginsUnconditionally: this.#showOriginsUnconditionally,
326
+ overviewSecurityState: this.#overviewSecurityState,
327
+ selectedElementId: this.#selectedElementId,
328
+ };
329
+ const output: ViewOutput = {
330
+ onElementSelected: (id: string) => {
331
+ this.#selectedElementId = id;
332
+ this.#securitySidebarLastItemSetting.set(id);
333
+ this.requestUpdate();
334
+ },
335
+ onShowOrigin: (origin: Platform.DevToolsPath.UrlString|null) => {
336
+ this.#onShowOrigin?.(origin);
337
+ },
338
+ };
339
+ this.#view(input, output, this.contentElement);
300
340
  }
301
341
  }
@@ -2,16 +2,12 @@
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
4
 
5
- import * as OriginTreeElement from './OriginTreeElement.js';
6
5
  import * as SecurityModel from './SecurityModel.js';
7
6
  import * as SecurityPanel from './SecurityPanel.js';
8
7
  import * as SecurityPanelSidebar from './SecurityPanelSidebar.js';
9
- import * as SecurityPanelSidebarTreeElement from './SecurityPanelSidebarTreeElement.js';
10
8
 
11
9
  export {
12
- OriginTreeElement,
13
10
  SecurityModel,
14
11
  SecurityPanel,
15
12
  SecurityPanelSidebar,
16
- SecurityPanelSidebarTreeElement,
17
13
  };
@@ -6,7 +6,7 @@ import '../../ui/legacy/components/data_grid/data_grid.js';
6
6
 
7
7
  import * as i18n from '../../core/i18n/i18n.js';
8
8
  import * as Platform from '../../core/platform/platform.js';
9
- import type {PlatformFileSystem} from '../../models/persistence/PlatformFileSystem.js';
9
+ import type * as Persistence from '../../models/persistence/persistence.js';
10
10
  import * as UI from '../../ui/legacy/legacy.js';
11
11
  import {Directives, html, render} from '../../ui/lit/lit.js';
12
12
 
@@ -104,7 +104,7 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
104
104
  };
105
105
 
106
106
  export class EditFileSystemView extends UI.Widget.VBox {
107
- #fileSystem?: PlatformFileSystem;
107
+ #fileSystem?: Persistence.PlatformFileSystem.PlatformFileSystem;
108
108
  #excludedFolderPaths: PathWithStatus[] = [];
109
109
  readonly #view: View;
110
110
 
@@ -113,7 +113,7 @@ export class EditFileSystemView extends UI.Widget.VBox {
113
113
  this.#view = view;
114
114
  }
115
115
 
116
- set fileSystem(fileSystem: PlatformFileSystem) {
116
+ set fileSystem(fileSystem: Persistence.PlatformFileSystem.PlatformFileSystem) {
117
117
  this.#fileSystem = fileSystem;
118
118
  this.#resyncExcludedFolderPaths();
119
119
  this.requestUpdate();
@@ -126,10 +126,11 @@ export class EditFileSystemView extends UI.Widget.VBox {
126
126
  }
127
127
 
128
128
  #resyncExcludedFolderPaths(): void {
129
- this.#excludedFolderPaths = this.#fileSystem?.excludedFolders()
130
- .values()
131
- .map(path => ({path, status: ExcludedFolderStatus.VALID}))
132
- .toArray() ??
129
+ this.#excludedFolderPaths =
130
+ this.#fileSystem?.excludedFolders()
131
+ .values()
132
+ .map((path: Platform.DevToolsPath.EncodedPathString) => ({path, status: ExcludedFolderStatus.VALID}))
133
+ .toArray() ??
133
134
  [];
134
135
  }
135
136
 
@@ -7,6 +7,7 @@ import '../../ui/kit/kit.js';
7
7
 
8
8
  import * as Common from '../../core/common/common.js';
9
9
  import * as i18n from '../../core/i18n/i18n.js';
10
+ import * as Workspace from '../../models/workspace/workspace.js';
10
11
  import * as Buttons from '../../ui/components/buttons/buttons.js';
11
12
  import * as UIHelpers from '../../ui/helpers/helpers.js';
12
13
  import * as SettingsUI from '../../ui/legacy/components/settings_ui/settings_ui.js';
@@ -111,7 +112,8 @@ export class FrameworkIgnoreListSettingsTab extends UI.Widget.VBox implements
111
112
 
112
113
  const ignoreListingDescription = document.createElement('span');
113
114
  ignoreListingDescription.textContent = i18nString(UIStrings.ignoreListingDescription);
114
- const enabledSetting = Common.Settings.Settings.instance().moduleSetting('enable-ignore-listing');
115
+ const enabledSetting =
116
+ Common.Settings.Settings.instance().resolve(Workspace.IgnoreListManager.enableIgnoreListingSettingDescriptor);
115
117
  const enableIgnoreListing = this.contentElement.createChild('div', 'enable-ignore-listing');
116
118
  enableIgnoreListing.appendChild(
117
119
  SettingsUI.SettingsUI.createSettingCheckbox(i18nString(UIStrings.ignoreListing), enabledSetting));
@@ -123,17 +125,18 @@ export class FrameworkIgnoreListSettingsTab extends UI.Widget.VBox implements
123
125
 
124
126
  const generalExclusionGroup = this.createSettingGroup();
125
127
  generalExclusionGroup.classList.add('general-exclusion-group');
126
- const ignoreListContentScripts =
127
- generalExclusionGroup.createChild('div', 'ignore-list-option')
128
- .appendChild(SettingsUI.SettingsUI.createSettingCheckbox(
129
- i18nString(UIStrings.ignoreListContentScripts),
130
- Common.Settings.Settings.instance().moduleSetting('skip-content-scripts')));
128
+ const ignoreListContentScripts = generalExclusionGroup.createChild('div', 'ignore-list-option')
129
+ .appendChild(SettingsUI.SettingsUI.createSettingCheckbox(
130
+ i18nString(UIStrings.ignoreListContentScripts),
131
+ Common.Settings.Settings.instance().resolve(
132
+ Workspace.IgnoreListManager.skipContentScriptsSettingDescriptor)));
131
133
 
132
134
  const automaticallyIgnoreListContainer = generalExclusionGroup.createChild('div', 'ignore-list-option');
133
135
  const automaticallyIgnoreList =
134
136
  automaticallyIgnoreListContainer.appendChild(SettingsUI.SettingsUI.createSettingCheckbox(
135
137
  i18nString(UIStrings.automaticallyIgnoreListKnownThirdPartyScripts),
136
- Common.Settings.Settings.instance().moduleSetting('automatically-ignore-list-known-third-party-scripts')));
138
+ Common.Settings.Settings.instance().resolve(
139
+ Workspace.IgnoreListManager.automaticallyIgnoreListKnownThirdPartyScriptsSettingDescriptor)));
137
140
 
138
141
  const automaticallyIgnoreLinkButton = new Buttons.Button.Button();
139
142
  automaticallyIgnoreLinkButton.data = {
@@ -149,11 +152,11 @@ export class FrameworkIgnoreListSettingsTab extends UI.Widget.VBox implements
149
152
  'https://developer.chrome.com/docs/devtools/settings/ignore-list/#skip-third-party'));
150
153
  automaticallyIgnoreListContainer.appendChild(automaticallyIgnoreLinkButton);
151
154
 
152
- const ignoreListAnonymousScripts =
153
- generalExclusionGroup.createChild('div', 'ignore-list-option')
154
- .appendChild(SettingsUI.SettingsUI.createSettingCheckbox(
155
- i18nString(UIStrings.ignoreListAnonymousScripts),
156
- Common.Settings.Settings.instance().moduleSetting('skip-anonymous-scripts')));
155
+ const ignoreListAnonymousScripts = generalExclusionGroup.createChild('div', 'ignore-list-option')
156
+ .appendChild(SettingsUI.SettingsUI.createSettingCheckbox(
157
+ i18nString(UIStrings.ignoreListAnonymousScripts),
158
+ Common.Settings.Settings.instance().resolve(
159
+ Workspace.IgnoreListManager.skipAnonymousScriptsSettingDescriptor)));
157
160
 
158
161
  const generalExclusionGroupCard = settingsContent.createChild('devtools-card', 'ignore-list-options');
159
162
  generalExclusionGroupCard.heading = i18nString(UIStrings.generalExclusionRules);
@@ -179,7 +182,8 @@ export class FrameworkIgnoreListSettingsTab extends UI.Widget.VBox implements
179
182
  UI.ARIAUtils.setLabel(addPatternButton, i18nString(UIStrings.addFilenamePattern));
180
183
  customExclusionGroup.appendChild(addPatternButton);
181
184
  this.setting =
182
- Common.Settings.Settings.instance().moduleSetting('skip-stack-frames-pattern') as Common.Settings.RegExpSetting;
185
+ Common.Settings.Settings.instance().resolve(
186
+ Workspace.IgnoreListManager.skipStackFramesPatternSettingDescriptor) as Common.Settings.RegExpSetting;
183
187
  this.setting.addChangeListener(this.settingUpdated, this);
184
188
 
185
189
  const enabledChanged = (): void => {
@@ -202,7 +206,9 @@ export class FrameworkIgnoreListSettingsTab extends UI.Widget.VBox implements
202
206
  }
203
207
 
204
208
  private settingUpdated(): void {
205
- const editable = Common.Settings.Settings.instance().moduleSetting<boolean>('enable-ignore-listing').get();
209
+ const editable = Common.Settings.Settings.instance()
210
+ .resolve(Workspace.IgnoreListManager.enableIgnoreListingSettingDescriptor)
211
+ .get();
206
212
  this.list.clear();
207
213
  const patterns = this.setting.getAsArray();
208
214
  for (let i = 0; i < patterns.length; ++i) {