chrome-devtools-frontend 1.0.1675430 → 1.0.1676824

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 (225) hide show
  1. package/WATCHLISTS +0 -4
  2. package/front_end/core/common/Settings.ts +0 -66
  3. package/front_end/core/root/Runtime.ts +0 -5
  4. package/front_end/core/sdk/CSSMetadata.ts +5 -9
  5. package/front_end/core/sdk/CSSPropertyParserMatchers.ts +8 -28
  6. package/front_end/core/sdk/DebuggerModel.ts +50 -30
  7. package/front_end/core/sdk/ResourceTreeModel.ts +20 -1
  8. package/front_end/core/sdk/Script.ts +9 -53
  9. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +213 -23
  10. package/front_end/entrypoints/main/MainImpl.ts +31 -0
  11. package/front_end/generated/InspectorBackendCommands.ts +3 -1
  12. package/front_end/generated/SupportedCSSProperties.ts +21 -4
  13. package/front_end/generated/protocol-mapping.d.ts +14 -0
  14. package/front_end/generated/protocol-proxy-api.d.ts +10 -0
  15. package/front_end/generated/protocol.ts +35 -0
  16. package/front_end/models/ai_assistance/AiAgent2.ts +11 -0
  17. package/front_end/models/ai_assistance/AiConversation.ts +22 -5
  18. package/front_end/models/ai_assistance/README.md +52 -26
  19. package/front_end/models/ai_assistance/agents/AiAgent.ts +54 -8
  20. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +1 -1
  21. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +7 -194
  22. package/front_end/models/ai_assistance/agents/StorageAgent.ts +8 -87
  23. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +2 -1
  24. package/front_end/models/ai_assistance/ai_assistance.ts +16 -0
  25. package/front_end/models/ai_assistance/contexts/PerformanceTraceContext.ts +124 -0
  26. package/front_end/models/ai_assistance/contexts/StorageContext.ts +111 -0
  27. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +69 -1
  28. package/front_end/models/ai_assistance/skills/README.md +63 -1
  29. package/front_end/models/ai_assistance/skills/Skill.ts +1 -1
  30. package/front_end/models/ai_assistance/skills/SkillRegistry.ts +4 -0
  31. package/front_end/models/ai_assistance/skills/performance.md +8 -0
  32. package/front_end/models/ai_assistance/skills/sources.md +16 -0
  33. package/front_end/models/ai_assistance/skills/storage.md +31 -0
  34. package/front_end/models/ai_assistance/tools/GetSourceContent.ts +101 -0
  35. package/front_end/models/ai_assistance/tools/GetTraceEventByKey.ts +83 -0
  36. package/front_end/models/ai_assistance/tools/GetTraceMainThreadSummary.ts +106 -0
  37. package/front_end/models/ai_assistance/tools/GetTraceNetworkSummary.ts +104 -0
  38. package/front_end/models/ai_assistance/tools/ListPageOrigins.ts +81 -0
  39. package/front_end/models/ai_assistance/tools/ListSources.ts +116 -0
  40. package/front_end/models/ai_assistance/tools/SelectTraceEventByKey.ts +90 -0
  41. package/front_end/models/ai_assistance/tools/Tool.ts +22 -1
  42. package/front_end/models/ai_assistance/tools/ToolRegistry.ts +14 -0
  43. package/front_end/models/bindings/CSSWorkspaceBinding.ts +4 -0
  44. package/front_end/models/bindings/CompilerScriptMapping.ts +4 -0
  45. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +8 -0
  46. package/front_end/models/bindings/ResourceScriptMapping.ts +3 -201
  47. package/front_end/models/bindings/SASSSourceMapping.ts +6 -0
  48. package/front_end/models/breakpoints/BreakpointManager.ts +2 -49
  49. package/front_end/models/heap_snapshot/HeapSnapshotModel.ts +27 -0
  50. package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +10 -2
  51. package/front_end/models/issues_manager/descriptions/connectionAllowlistEmbeddingRequirementNotSatisfied.md +26 -0
  52. package/front_end/models/issues_manager/descriptions/connectionAllowlistIFrameAttributeLoosensEmbeddingRequirement.md +19 -0
  53. package/front_end/models/issues_manager/descriptions/connectionAllowlistInvalidAllowConnectionAllowlistFrom.md +21 -0
  54. package/front_end/models/javascript_metadata/NativeFunctions.js +1 -1
  55. package/front_end/models/persistence/IsolatedFileSystem.ts +7 -8
  56. package/front_end/models/persistence/IsolatedFileSystemManager.ts +2 -2
  57. package/front_end/models/persistence/PlatformFileSystem.ts +1 -1
  58. package/front_end/models/persistence/persistence-meta.ts +9 -9
  59. package/front_end/models/trace/types/TraceEvents.ts +36 -0
  60. package/front_end/panels/accessibility/ARIAAttributesView.ts +3 -3
  61. package/front_end/panels/accessibility/AccessibilityNodeView.ts +36 -36
  62. package/front_end/panels/accessibility/AccessibilityStrings.ts +168 -168
  63. package/front_end/panels/accessibility/SourceOrderView.ts +7 -7
  64. package/front_end/panels/accessibility/accessibility-meta.ts +2 -2
  65. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +5 -5
  66. package/front_end/panels/ai_assistance/components/AIv2MarkdownRenderer.ts +2 -3
  67. package/front_end/panels/ai_assistance/components/ChatInput.ts +2 -2
  68. package/front_end/panels/ai_assistance/components/ChatMessage.ts +27 -2
  69. package/front_end/panels/application/IndexedDBViews.ts +65 -63
  70. package/front_end/panels/application/WebMCPView.ts +16 -7
  71. package/front_end/panels/common/AiCodeCompletionSummaryToolbar.ts +5 -5
  72. package/front_end/panels/common/BadgeNotification.ts +8 -8
  73. package/front_end/panels/common/ExtensionServer.ts +21 -1
  74. package/front_end/panels/common/GdpSignUpDialog.ts +16 -16
  75. package/front_end/panels/common/GeminiRebrandPromoDialog.ts +5 -6
  76. package/front_end/panels/common/PersistenceUtils.ts +2 -2
  77. package/front_end/panels/common/common.ts +0 -97
  78. package/front_end/panels/console/ConsoleInsightTeaser.ts +2 -2
  79. package/front_end/panels/console/ConsolePinPane.ts +2 -2
  80. package/front_end/panels/console/ConsoleView.ts +20 -19
  81. package/front_end/panels/elements/LayoutPane.ts +2 -8
  82. package/front_end/panels/event_listeners/EventListenersView.ts +8 -4
  83. package/front_end/panels/issues/AffectedTrackingSitesView.ts +25 -14
  84. package/front_end/panels/media/PlayerMessagesView.ts +149 -68
  85. package/front_end/panels/network/NetworkPanel.ts +1 -1
  86. package/front_end/panels/network/RequestPayloadView.ts +1 -0
  87. package/front_end/panels/profiler/HeapSnapshotView.ts +0 -2
  88. package/front_end/panels/profiler/heapProfiler.css +0 -9
  89. package/front_end/panels/recorder/RecorderPanel.ts +2 -3
  90. package/front_end/panels/screencast/ScreencastView.ts +148 -138
  91. package/front_end/panels/sources/AiCodeCompletionPlugin.ts +2 -2
  92. package/front_end/panels/sources/DebuggerPlugin.ts +9 -58
  93. package/front_end/panels/sources/ScopeChainSidebarPane.ts +1 -1
  94. package/front_end/panels/sources/UISourceCodeFrame.ts +3 -8
  95. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +4 -2
  96. package/front_end/panels/timeline/TimelineController.ts +36 -64
  97. package/front_end/panels/timeline/TimelinePanel.ts +11 -8
  98. package/front_end/panels/timeline/TimelineUIUtils.ts +5 -2
  99. package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +2 -2
  100. package/front_end/panels/timeline/timelinePanel.css +0 -10
  101. package/front_end/panels/utils/utils.ts +7 -7
  102. package/front_end/services/tracing/PerformanceTracing.ts +5 -17
  103. package/front_end/third_party/chromium/README.chromium +1 -1
  104. package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
  105. package/front_end/third_party/codemirror.next/chunk/codemirror.js.map +1 -1
  106. package/front_end/third_party/codemirror.next/package.json +2 -2
  107. package/front_end/third_party/codemirror.next/rebuild.sh +4 -1
  108. package/front_end/ui/comments/CommentAnchorResolver.ts +436 -10
  109. package/front_end/ui/comments/CommentManager.ts +640 -0
  110. package/front_end/ui/comments/CommentsOverlayWidget.ts +121 -0
  111. package/front_end/ui/comments/comments.ts +4 -0
  112. package/front_end/ui/comments/commentsOverlay.css +49 -0
  113. package/front_end/{panels/common → ui/components/dialogs}/FreDialog.ts +6 -6
  114. package/front_end/ui/components/dialogs/TypeToAllowDialog.ts +96 -0
  115. package/front_end/ui/components/dialogs/dialogs.ts +4 -0
  116. package/front_end/ui/components/settings/SettingCheckbox.ts +3 -3
  117. package/front_end/{panels/common → ui/components/text_editor}/AiCodeCompletionDisclaimer.ts +13 -13
  118. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +7 -6
  119. package/front_end/{panels/common → ui/components/text_editor}/AiCodeCompletionTeaser.ts +43 -46
  120. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +22 -26
  121. package/front_end/{panels/common → ui/components/text_editor}/AiCodeGenerationTeaser.ts +10 -10
  122. package/front_end/{panels/common → ui/components/text_editor}/AiCodeGenerationUpgradeDialog.ts +5 -5
  123. package/front_end/ui/components/text_editor/text_editor.ts +4 -0
  124. package/front_end/ui/legacy/Toolbar.ts +1 -1
  125. package/front_end/ui/legacy/components/object_ui/CustomPreviewComponent.ts +11 -3
  126. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +270 -162
  127. package/front_end/ui/legacy/components/object_ui/objectPropertiesSection.css +5 -0
  128. package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +11 -16
  129. package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +5 -12
  130. package/front_end/ui/legacy/components/source_frame/JSONView.ts +8 -1
  131. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +2 -2
  132. package/front_end/ui/settings/SettingUIRegistration.ts +55 -6
  133. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
  134. package/mcp/mcp.ts +6 -1
  135. package/package.json +1 -1
  136. package/front_end/Images/toolbarResizerVertical.png +0 -0
  137. package/front_end/emulated_devices/MotoG4-landscape.svg +0 -155
  138. package/front_end/emulated_devices/MotoG4-portrait.svg +0 -155
  139. package/front_end/emulated_devices/Nexus5X-landscape.svg +0 -19
  140. package/front_end/emulated_devices/Nexus5X-portrait.svg +0 -19
  141. package/front_end/emulated_devices/Nexus6P-landscape.svg +0 -50
  142. package/front_end/emulated_devices/Nexus6P-portrait.svg +0 -54
  143. package/front_end/emulated_devices/google-nest-hub-horizontal.png +0 -0
  144. package/front_end/emulated_devices/google-nest-hub-max-horizontal.png +0 -0
  145. package/front_end/emulated_devices/google-nexus-5-horizontal-default-1x.png +0 -0
  146. package/front_end/emulated_devices/google-nexus-5-horizontal-default-2x.png +0 -0
  147. package/front_end/emulated_devices/google-nexus-5-horizontal-keyboard-1x.png +0 -0
  148. package/front_end/emulated_devices/google-nexus-5-horizontal-keyboard-2x.png +0 -0
  149. package/front_end/emulated_devices/google-nexus-5-horizontal-navigation-1x.png +0 -0
  150. package/front_end/emulated_devices/google-nexus-5-horizontal-navigation-2x.png +0 -0
  151. package/front_end/emulated_devices/google-nexus-5-vertical-default-1x.png +0 -0
  152. package/front_end/emulated_devices/google-nexus-5-vertical-default-2x.png +0 -0
  153. package/front_end/emulated_devices/google-nexus-5-vertical-keyboard-1x.png +0 -0
  154. package/front_end/emulated_devices/google-nexus-5-vertical-keyboard-2x.png +0 -0
  155. package/front_end/emulated_devices/google-nexus-5-vertical-navigation-1x.png +0 -0
  156. package/front_end/emulated_devices/google-nexus-5-vertical-navigation-2x.png +0 -0
  157. package/front_end/emulated_devices/google-nexus-5x-horizontal-default-1x.png +0 -0
  158. package/front_end/emulated_devices/google-nexus-5x-horizontal-default-2x.png +0 -0
  159. package/front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-1x.png +0 -0
  160. package/front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-2x.png +0 -0
  161. package/front_end/emulated_devices/google-nexus-5x-horizontal-navigation-1x.png +0 -0
  162. package/front_end/emulated_devices/google-nexus-5x-horizontal-navigation-2x.png +0 -0
  163. package/front_end/emulated_devices/google-nexus-5x-vertical-default-1x.png +0 -0
  164. package/front_end/emulated_devices/google-nexus-5x-vertical-default-2x.png +0 -0
  165. package/front_end/emulated_devices/google-nexus-5x-vertical-keyboard-1x.png +0 -0
  166. package/front_end/emulated_devices/google-nexus-5x-vertical-keyboard-2x.png +0 -0
  167. package/front_end/emulated_devices/google-nexus-5x-vertical-navigation-1x.png +0 -0
  168. package/front_end/emulated_devices/google-nexus-5x-vertical-navigation-2x.png +0 -0
  169. package/front_end/emulated_devices/iPad-landscape.svg +0 -73
  170. package/front_end/emulated_devices/iPad-portrait.svg +0 -76
  171. package/front_end/emulated_devices/iPhone5-landscape.svg +0 -99
  172. package/front_end/emulated_devices/iPhone5-portrait.svg +0 -83
  173. package/front_end/emulated_devices/iPhone6-landscape.svg +0 -111
  174. package/front_end/emulated_devices/iPhone6-portrait.svg +0 -116
  175. package/front_end/emulated_devices/iPhone6Plus-landscape.svg +0 -118
  176. package/front_end/emulated_devices/iPhone6Plus-portrait.svg +0 -116
  177. package/front_end/emulated_devices/optimized/MotoG4-landscape.avif +0 -0
  178. package/front_end/emulated_devices/optimized/MotoG4-portrait.avif +0 -0
  179. package/front_end/emulated_devices/optimized/Nexus5X-landscape.avif +0 -0
  180. package/front_end/emulated_devices/optimized/Nexus5X-portrait.avif +0 -0
  181. package/front_end/emulated_devices/optimized/Nexus6P-landscape.avif +0 -0
  182. package/front_end/emulated_devices/optimized/Nexus6P-portrait.avif +0 -0
  183. package/front_end/emulated_devices/optimized/README.md +0 -9
  184. package/front_end/emulated_devices/optimized/google-nest-hub-horizontal.avif +0 -0
  185. package/front_end/emulated_devices/optimized/google-nest-hub-max-horizontal.avif +0 -0
  186. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-default-1x.avif +0 -0
  187. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-default-2x.avif +0 -0
  188. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-keyboard-1x.avif +0 -0
  189. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-keyboard-2x.avif +0 -0
  190. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-navigation-1x.avif +0 -0
  191. package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-navigation-2x.avif +0 -0
  192. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-default-1x.avif +0 -0
  193. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-default-2x.avif +0 -0
  194. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-keyboard-1x.avif +0 -0
  195. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-keyboard-2x.avif +0 -0
  196. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-navigation-1x.avif +0 -0
  197. package/front_end/emulated_devices/optimized/google-nexus-5-vertical-navigation-2x.avif +0 -0
  198. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-default-1x.avif +0 -0
  199. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-default-2x.avif +0 -0
  200. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-keyboard-1x.avif +0 -0
  201. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-keyboard-2x.avif +0 -0
  202. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-navigation-1x.avif +0 -0
  203. package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-navigation-2x.avif +0 -0
  204. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-default-1x.avif +0 -0
  205. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-default-2x.avif +0 -0
  206. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-keyboard-1x.avif +0 -0
  207. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-keyboard-2x.avif +0 -0
  208. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-navigation-1x.avif +0 -0
  209. package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-navigation-2x.avif +0 -0
  210. package/front_end/emulated_devices/optimized/iPad-landscape.avif +0 -0
  211. package/front_end/emulated_devices/optimized/iPad-portrait.avif +0 -0
  212. package/front_end/emulated_devices/optimized/iPhone5-landscape.avif +0 -0
  213. package/front_end/emulated_devices/optimized/iPhone5-portrait.avif +0 -0
  214. package/front_end/emulated_devices/optimized/iPhone6-landscape.avif +0 -0
  215. package/front_end/emulated_devices/optimized/iPhone6-portrait.avif +0 -0
  216. package/front_end/emulated_devices/optimized/iPhone6Plus-landscape.avif +0 -0
  217. package/front_end/emulated_devices/optimized/iPhone6Plus-portrait.avif +0 -0
  218. package/front_end/emulated_devices/optimized/optimized_images.gni +0 -53
  219. package/front_end/models/ai_assistance/agents/README.md +0 -136
  220. /package/front_end/{panels/common → ui/components/dialogs}/freDialog.css +0 -0
  221. /package/front_end/{panels/common/common.css → ui/components/dialogs/typeToAllowDialog.css} +0 -0
  222. /package/front_end/{panels/common → ui/components/text_editor}/aiCodeCompletionDisclaimer.css +0 -0
  223. /package/front_end/{panels/common → ui/components/text_editor}/aiCodeCompletionTeaser.css +0 -0
  224. /package/front_end/{panels/common → ui/components/text_editor}/aiCodeGenerationTeaser.css +0 -0
  225. /package/front_end/{panels/common → ui/components/text_editor}/aiCodeGenerationUpgradeDialog.css +0 -0
@@ -64,8 +64,8 @@ export interface ObjectPropertySearchResult extends UI.TreeOutline.TreeSearchRes
64
64
  matchType: 'name'|'value';
65
65
  range: TextUtils.TextRange.SourceRange;
66
66
  }
67
- const {widget} = UI.Widget;
68
- const {ref, repeat, ifDefined, classMap, until} = Directives;
67
+ const {widget, widgetRef} = UI.Widget;
68
+ const {ref, repeat, ifDefined, classMap} = Directives;
69
69
  const UIStrings = {
70
70
  /**
71
71
  * @description Text in Object Properties Section
@@ -167,6 +167,7 @@ const objectPropertiesSectionMap = new WeakMap<Element, ObjectPropertiesSection>
167
167
  // the legacy TreeOutline/TreeElement dependencies are removed.
168
168
  const topLevelNodesCache = new WeakMap<ObjectTreeNodeBase, {
169
169
  nodes: UI.TreeOutline.TreeElement[],
170
+ listener: () => void,
170
171
  linkifier?: Components.Linkifier.Linkifier,
171
172
  }>();
172
173
 
@@ -488,7 +489,7 @@ export abstract class ObjectTreeNodeBase extends Common.ObjectWrapper.ObjectWrap
488
489
  yield* child.#walk(Math.max(-1, maxDepth - 1), filter);
489
490
  }
490
491
  }
491
- }
492
+ }
492
493
 
493
494
  async expandRecursively(maxDepth: number): Promise<void> {
494
495
  for (const node of this.#walk(maxDepth, n => n.canExpandRecursively)) {
@@ -968,33 +969,6 @@ export class ObjectPropertiesSection extends UI.TreeOutline.TreeOutlineInShadow
968
969
  this.rootElement().childrenListElement.classList.add('source-code', 'object-properties-section');
969
970
  }
970
971
 
971
- static defaultObjectPresentation(object: SDK.RemoteObject.RemoteObject, linkifier?: Components.Linkifier.Linkifier,
972
- skipProto?: boolean, readOnly?: boolean): Element {
973
- const objectPropertiesSection =
974
- ObjectPropertiesSection.defaultObjectPropertiesSection(object, linkifier, skipProto, readOnly);
975
- if (!object.hasChildren) {
976
- return objectPropertiesSection.titleElement;
977
- }
978
- return objectPropertiesSection.element;
979
- }
980
-
981
- static defaultObjectPropertiesSection(object: SDK.RemoteObject.RemoteObject,
982
- linkifier?: Components.Linkifier.Linkifier, skipProto?: boolean,
983
- readOnly?: boolean): ObjectPropertiesSection {
984
- const titleElement = document.createElement('span');
985
- titleElement.classList.add('source-code');
986
- const shadowRoot = UI.UIUtils.createShadowRootWithCoreStyles(titleElement, {cssFile: objectValueStyles});
987
- const propertyValue =
988
- ObjectPropertiesSection.createPropertyValue(object, /* wasThrown */ false, /* showPreview */ true);
989
- shadowRoot.appendChild(propertyValue);
990
- const objectPropertiesSection = new ObjectPropertiesSection(object, titleElement, linkifier, undefined, !readOnly);
991
- if (skipProto) {
992
- objectPropertiesSection.skipProto();
993
- }
994
-
995
- return objectPropertiesSection;
996
- }
997
-
998
972
  // The RemoteObjectProperty overload is kept for web test compatibility for now.
999
973
  static compareProperties(propertyA: ObjectTreeNode|SDK.RemoteObject.RemoteObjectProperty,
1000
974
  propertyB: ObjectTreeNode|SDK.RemoteObject.RemoteObjectProperty,
@@ -1144,19 +1118,6 @@ export class ObjectPropertiesSection extends UI.TreeOutline.TreeOutlineInShadow
1144
1118
  }
1145
1119
  }
1146
1120
 
1147
- static createPropertyValueWithCustomSupport(value: SDK.RemoteObject.RemoteObject, wasThrown: boolean,
1148
- showPreview: boolean, linkifier?: Components.Linkifier.Linkifier,
1149
- isSyntheticProperty?: boolean, variableName?: string,
1150
- includeNullOrUndefined?: boolean): HTMLElement {
1151
- if (value.customPreview()) {
1152
- const result = (new CustomPreviewComponent(value)).element;
1153
- result.classList.add('object-properties-section-custom-section');
1154
- return result;
1155
- }
1156
- return ObjectPropertiesSection.createPropertyValue(value, wasThrown, showPreview, linkifier, isSyntheticProperty,
1157
- variableName, includeNullOrUndefined);
1158
- }
1159
-
1160
1121
  static getMemoryIcon(object: SDK.RemoteObject.RemoteObject, expression?: string): LitTemplate {
1161
1122
  // Directly set styles on memory icon, so that the memory icon is also
1162
1123
  // styled within the context of code mirror.
@@ -1181,81 +1142,6 @@ export class ObjectPropertiesSection extends UI.TreeOutline.TreeOutlineInShadow
1181
1142
  element.appendChild(fragment);
1182
1143
  }
1183
1144
 
1184
- static createPropertyValue(value: SDK.RemoteObject.RemoteObject, wasThrown: boolean, showPreview: boolean,
1185
- linkifier?: Components.Linkifier.Linkifier, isSyntheticProperty = false,
1186
- variableName?: string, includeNullOrUndefined?: boolean): HTMLElement {
1187
- const propertyValue = document.createDocumentFragment();
1188
- const type = value.type;
1189
- const subtype = value.subtype;
1190
- const description = value.description || '';
1191
- const className = value.className;
1192
-
1193
- const contents = (): LitTemplate => {
1194
- if (type === 'object' && subtype === 'internal#location') {
1195
- const rawLocation = value.debuggerModel().createRawLocationByScriptId(
1196
- value.value.scriptId, value.value.lineNumber, value.value.columnNumber);
1197
- if (rawLocation && linkifier) {
1198
- return html`${linkifier.linkifyRawLocation(rawLocation, Platform.DevToolsPath.EmptyUrlString, 'value')}`;
1199
- }
1200
- const title = description || undefined;
1201
- return html`<span class=value title=${ifDefined(title)}>${'<' + i18nString(UIStrings.unknown) + '>'}</span>`;
1202
- }
1203
- if (type === 'string' && typeof description === 'string') {
1204
- const text = Platform.StringUtilities.escapeUnicodeAsText(JSON.stringify(description));
1205
- const tooLong = description.length > maxRenderableStringLength;
1206
- return html`<span class="value object-value-string" title=${ifDefined(tooLong ? undefined : description)}>${
1207
- tooLong ? widget(ExpandableTextPropertyValue, {text}) : text}</span>`;
1208
- }
1209
- if (type === 'object' && subtype === 'trustedtype') {
1210
- const text = `${className} "${description}"`;
1211
- const tooLong = text.length > maxRenderableStringLength;
1212
- return html`<span class="value object-value-trustedtype" title=${ifDefined(tooLong ? undefined : text)}>${
1213
- tooLong ? widget(ExpandableTextPropertyValue, {text}) : renderTrustedType(description, className)}</span>`;
1214
- }
1215
- if (type === 'function') {
1216
- return html`<span class="value">${
1217
- ObjectPropertiesSection.valueElementForFunctionDescription(description)}</span>`;
1218
- }
1219
- if (type === 'object' && subtype === 'node' && description) {
1220
- return html`<span class="value object-value-node"
1221
- @click=${(event: Event) => {
1222
- void Common.Revealer.reveal(value);
1223
- event.consume(true);
1224
- }}
1225
- @mousemove=${() => SDK.OverlayModel.OverlayModel.highlightObjectAsDOMNode(value)}
1226
- @mouseleave=${
1227
- () => SDK.OverlayModel.OverlayModel.hideDOMNodeHighlight(SDK.TargetManager.TargetManager.instance())}
1228
- >${renderNodeTitle(description)}</span>`;
1229
- }
1230
- if (description.length > maxRenderableStringLength) {
1231
- // clang-format off
1232
- return html`<span class="value object-value-${subtype || type}" title=${description}>
1233
- ${widget(ExpandableTextPropertyValue, {text: description})}
1234
- </span>`;
1235
- // clang-format on
1236
- }
1237
- const hasPreview = value.preview && showPreview;
1238
- return html`<span class="value object-value-${subtype || type}" title=${description}>${
1239
- hasPreview ? new RemoteObjectPreviewFormatter().renderObjectPreview(value.preview, includeNullOrUndefined) :
1240
- description}${isSyntheticProperty ? nothing : this.getMemoryIcon(value, variableName)}</span>`;
1241
- };
1242
-
1243
- if (wasThrown) {
1244
- // eslint-disable-next-line @devtools/no-lit-render-outside-of-view
1245
- render(html`<span class="error value">${
1246
- uiI18n.getFormatLocalizedStringTemplate(str_, UIStrings.exceptionS, {PH1: contents()})}</span>`,
1247
- propertyValue);
1248
- } else {
1249
- // eslint-disable-next-line @devtools/no-lit-render-outside-of-view
1250
- render(contents(), propertyValue);
1251
- }
1252
- const child = propertyValue.firstElementChild;
1253
- if (!(child instanceof HTMLElement)) {
1254
- throw new Error('Expected an HTML element');
1255
- }
1256
- return child;
1257
- }
1258
-
1259
1145
  static isDisplayableProperty(property: SDK.RemoteObject.RemoteObjectProperty,
1260
1146
  parentProperty?: SDK.RemoteObject.RemoteObjectProperty): boolean {
1261
1147
  if (!parentProperty?.synthetic) {
@@ -1366,70 +1252,177 @@ export function populateObjectTreeContextMenu(
1366
1252
  {checked: object.includeNullOrUndefinedValues, jslogContext: 'show-all'});
1367
1253
  }
1368
1254
 
1369
- function renderObjectTreeInternal(
1370
- objectTree: ObjectTree,
1371
- linkifier?: Components.Linkifier.Linkifier,
1372
- emptyPlaceholder?: string|null,
1373
- classes: Record<string, boolean> = {},
1374
- ): LitTemplate|DirectiveResult {
1375
- const entry = topLevelNodesCache.get(objectTree);
1376
- if (entry && entry.linkifier === linkifier) {
1377
- return html`
1378
- <ul class=${classMap(classes)} role="group">
1379
- ${entry.nodes.map(node => html`<devtools-tree-wrapper .treeElement=${node}></devtools-tree-wrapper>`)}
1380
- </ul>
1381
- `;
1382
- }
1383
-
1384
- const promise = (async () => {
1385
- await ObjectPropertyTreeElement.populateChildrenIfNeeded(objectTree);
1386
- const nodes = Array.from(ObjectPropertyTreeElement.createNodes(
1387
- objectTree, /* skipProto= */ false, /* skipGettersAndSetters= */ false, linkifier, emptyPlaceholder));
1388
- topLevelNodesCache.set(objectTree, {linkifier, nodes});
1255
+ interface ObjectTreeViewInput {
1256
+ renderAsSubtree: boolean;
1257
+ objectTree?: ObjectTree;
1258
+ linkifier?: Components.Linkifier.Linkifier;
1259
+ emptyPlaceholder?: string;
1260
+ skipProto: boolean;
1261
+ onExpand: (expanded: boolean) => void;
1262
+ }
1263
+ type ObjectTreeView = (input: ObjectTreeViewInput, output: object, target: HTMLElement) => void;
1264
+ export const OBJECT_TREE_DEFAULT_VIEW: ObjectTreeView = (input, output, target) => {
1265
+ const objectTree = input.objectTree;
1266
+ if (!objectTree) {
1267
+ render(nothing, target);
1268
+ return;
1269
+ }
1270
+ const classes = input.renderAsSubtree ? ['source-code', 'object-properties-section'] : [];
1271
+ let entry = topLevelNodesCache.get(objectTree);
1272
+ if (!entry || entry.linkifier !== input.linkifier || (!entry.nodes.length && objectTree.children)) {
1273
+ if (entry) {
1274
+ objectTree.removeEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, entry.listener);
1275
+ }
1276
+ const nodes = Array.from(ObjectPropertyTreeElement.createNodes(objectTree, input.skipProto, false, input.linkifier,
1277
+ input.emptyPlaceholder));
1389
1278
  const listener = (): void => {
1390
1279
  topLevelNodesCache.delete(objectTree);
1391
1280
  objectTree.removeEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, listener);
1392
1281
  };
1282
+ entry = {linkifier: input.linkifier, nodes, listener};
1283
+ topLevelNodesCache.set(objectTree, entry);
1393
1284
  objectTree.addEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, listener);
1285
+ }
1394
1286
 
1395
- return html`
1396
- <ul class=${classMap(classes)} role="group">
1397
- ${nodes.map(node => html`<devtools-tree-wrapper .treeElement=${node}></devtools-tree-wrapper>`)}
1398
- </ul>
1399
- `;
1400
- })();
1287
+ render(entry.nodes.map(node => html`<devtools-tree-wrapper .treeElement=${node}></devtools-tree-wrapper>`), target, {
1288
+ container: {
1289
+ classes,
1290
+ attributes: {role: 'group'},
1291
+ interceptedListeners: {
1292
+ expand: (e: Event) => input.onExpand((e as UI.TreeOutline.TreeViewElement.ExpandEvent).detail.expanded),
1293
+ },
1294
+ },
1295
+ });
1296
+ };
1297
+
1298
+ export class ObjectTreeWidget extends UI.Widget.Widget {
1299
+ #objectTree: ObjectTree|undefined = undefined;
1300
+ #linkifier: Components.Linkifier.Linkifier|undefined = undefined;
1301
+ #emptyPlaceholder?: string;
1302
+ #renderAsSubtree = false;
1303
+ #skipProto = false;
1304
+ readonly #view: ObjectTreeView;
1305
+
1306
+ constructor(element?: HTMLElement, view = OBJECT_TREE_DEFAULT_VIEW) {
1307
+ super(element);
1308
+ this.#view = view;
1309
+ }
1401
1310
 
1402
- return until(promise, html`<ul class=${classMap(classes)} role="group"></ul>`);
1311
+ onExpand = (expanded: boolean): void => {
1312
+ if (this.#objectTree) {
1313
+ this.#objectTree.expanded = expanded;
1314
+ }
1315
+ };
1316
+
1317
+ get skipProto(): boolean {
1318
+ return this.#skipProto;
1319
+ }
1320
+ set skipProto(val: boolean) {
1321
+ this.#skipProto = val;
1322
+ this.requestUpdate();
1323
+ }
1324
+ get objectTree(): ObjectTree|undefined {
1325
+ return this.#objectTree;
1326
+ }
1327
+ set objectTree(val: ObjectTree) {
1328
+ if (val === this.#objectTree) {
1329
+ return;
1330
+ }
1331
+ this.#objectTree?.removeEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, this.requestUpdate, this);
1332
+ this.#objectTree?.removeEventListener(ObjectTreeNodeBase.Events.EXPANDED_CHANGED, this.requestUpdate, this);
1333
+ this.#objectTree = val;
1334
+ this.#objectTree?.addEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, this.requestUpdate, this);
1335
+ this.#objectTree?.addEventListener(ObjectTreeNodeBase.Events.EXPANDED_CHANGED, this.requestUpdate, this);
1336
+ this.requestUpdate();
1337
+ }
1338
+ get linkifier(): Components.Linkifier.Linkifier|undefined {
1339
+ return this.#linkifier;
1340
+ }
1341
+ set linkifier(val: Components.Linkifier.Linkifier) {
1342
+ if (val === this.#linkifier) {
1343
+ return;
1344
+ }
1345
+ this.#linkifier = val;
1346
+ this.requestUpdate();
1347
+ }
1348
+ get emptyPlaceholder(): string|undefined {
1349
+ return this.#emptyPlaceholder;
1350
+ }
1351
+ set emptyPlaceholder(val: string) {
1352
+ if (val === this.#emptyPlaceholder) {
1353
+ return;
1354
+ }
1355
+ this.#emptyPlaceholder = val;
1356
+ this.requestUpdate();
1357
+ }
1358
+
1359
+ get renderAsSubtree(): boolean {
1360
+ return this.#renderAsSubtree;
1361
+ }
1362
+ set renderAsSubtree(val: boolean) {
1363
+ if (val === this.#renderAsSubtree) {
1364
+ return;
1365
+ }
1366
+ this.#renderAsSubtree = val;
1367
+ this.requestUpdate();
1368
+ }
1369
+
1370
+ override async performUpdate(): Promise<void> {
1371
+ if (this.#objectTree?.expanded) {
1372
+ await ObjectPropertyTreeElement.populateChildrenIfNeeded(this.#objectTree);
1373
+ }
1374
+ this.#view(this, {}, this.contentElement);
1375
+ }
1376
+
1377
+ override onDetach(): void {
1378
+ this.#objectTree?.removeEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, this.requestUpdate, this);
1379
+ this.#objectTree?.removeEventListener(ObjectTreeNodeBase.Events.EXPANDED_CHANGED, this.requestUpdate, this);
1380
+ }
1381
+
1382
+ override wasShown(): void {
1383
+ super.wasShown();
1384
+ this.#objectTree?.removeEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, this.requestUpdate, this);
1385
+ this.#objectTree?.removeEventListener(ObjectTreeNodeBase.Events.EXPANDED_CHANGED, this.requestUpdate, this);
1386
+ this.#objectTree?.addEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, this.requestUpdate, this);
1387
+ this.#objectTree?.addEventListener(ObjectTreeNodeBase.Events.EXPANDED_CHANGED, this.requestUpdate, this);
1388
+ }
1403
1389
  }
1404
1390
 
1405
1391
  export function renderObjectTree(
1406
1392
  objectTree: ObjectTree,
1407
1393
  linkifier?: Components.Linkifier.Linkifier,
1408
- emptyPlaceholder?: string|null,
1394
+ emptyPlaceholder?: string,
1409
1395
  ): LitTemplate|DirectiveResult {
1410
- return renderObjectTreeInternal(objectTree, linkifier, emptyPlaceholder, {
1411
- 'source-code': true,
1412
- 'object-properties-section': true,
1413
- });
1396
+ return html`<ul role="group" ${
1397
+ widget(ObjectTreeWidget, {objectTree, linkifier, emptyPlaceholder, renderAsSubtree: true})} ${
1398
+ /* The empty widgetRef forces the widget to be materialized in the template DOM */
1399
+ widgetRef(ObjectTreeWidget, () => {})}></ul>`;
1414
1400
  }
1415
1401
 
1416
1402
  export function renderObjectPropertiesSection(
1417
1403
  objectTree: ObjectTree,
1418
1404
  title: LitTemplate,
1419
1405
  linkifier?: Components.Linkifier.Linkifier,
1406
+ skipProto = false,
1407
+ showOverflow = true,
1420
1408
  ): LitTemplate {
1421
- const treeContent = renderObjectTreeInternal(objectTree, linkifier, undefined, {});
1422
-
1423
- return html`<devtools-tree class="object-properties-section" show-selection-on-keyboard-focus .template=${html`
1409
+ // clang-format off
1410
+ return html`<devtools-tree
1411
+ class="object-properties-section"
1412
+ ?hide-overflow=${!showOverflow}
1413
+ show-selection-on-keyboard-focus
1414
+ .template=${html`
1424
1415
  <ul role="tree" class="source-code object-properties-section">
1425
1416
  <style>${objectValueStyles}</style>
1426
1417
  <style>${objectPropertiesSectionStyles}</style>
1427
1418
  <li role="treeitem" class="object-properties-section-root-element" ?open=${objectTree.expanded}>
1428
1419
  ${title}
1429
- ${treeContent}
1420
+ <ul role="group" ${widget(ObjectTreeWidget, {objectTree, linkifier, skipProto})} ${
1421
+ /* The empty widgetRef forces the widget to be materialized in the template DOM */
1422
+ widgetRef(ObjectTreeWidget, () => {})}></ul>
1430
1423
  </li>
1431
- </ul>
1432
- `}></devtools-tree>`;
1424
+ </ul>`}></devtools-tree>`;
1425
+ // clang-format on
1433
1426
  }
1434
1427
  class RootElement extends UI.TreeOutline.TreeElement {
1435
1428
  private readonly object: ObjectTree;
@@ -1525,6 +1518,121 @@ export async function formatObjectAsFunction(func: SDK.RemoteObject.RemoteObject
1525
1518
  details, linkify);
1526
1519
  }
1527
1520
 
1521
+ export function renderPropertyValue(value: SDK.RemoteObject.RemoteObject, wasThrown: boolean, showPreview: boolean,
1522
+ linkifier?: Components.Linkifier.Linkifier, isSyntheticProperty = false,
1523
+ variableName?: string, includeNullOrUndefined?: boolean, useCustomPreview = false,
1524
+ valueRef?: (element: Element|undefined) => void): LitTemplate {
1525
+ if (useCustomPreview && value.customPreview()) {
1526
+ const result = (new CustomPreviewComponent(value)).element;
1527
+ result.classList.add('object-properties-section-custom-section');
1528
+ valueRef?.(result);
1529
+ return html`${result}`;
1530
+ }
1531
+
1532
+ const type = value.type;
1533
+ const subtype = value.subtype;
1534
+ const description = value.description || '';
1535
+ const className = value.className;
1536
+
1537
+ const isInternalLocation = type === 'object' && subtype === 'internal#location';
1538
+ const isString = type === 'string' && typeof description === 'string';
1539
+ const isTrustedType = type === 'object' && subtype === 'trustedtype';
1540
+ const isFunction = type === 'function';
1541
+ const isNode = type === 'object' && subtype === 'node' && Boolean(description);
1542
+ const isDefault = !isInternalLocation && !isString && !isTrustedType && !isFunction && !isNode;
1543
+ const classes = classMap({
1544
+ value: true,
1545
+ [`object-value-${subtype || type}`]: isDefault,
1546
+ 'object-value-string': isString,
1547
+ 'object-value-trustedtype': isTrustedType,
1548
+ 'object-value-node': isNode,
1549
+ });
1550
+
1551
+ const onNodeClick = (event: Event): void => {
1552
+ void Common.Revealer.reveal(value);
1553
+ event.consume(true);
1554
+ };
1555
+ const onNodeMouseMove = (): void => SDK.OverlayModel.OverlayModel.highlightObjectAsDOMNode(value);
1556
+ const onNodeMouseLeave = (): void =>
1557
+ SDK.OverlayModel.OverlayModel.hideDOMNodeHighlight(SDK.TargetManager.TargetManager.instance());
1558
+
1559
+ let title: string|undefined;
1560
+ let content: LitTemplate|string|Element|DirectiveResult|null = description;
1561
+ if (isNode) {
1562
+ content = renderNodeTitle(description);
1563
+ } else if (isInternalLocation) {
1564
+ const rawLocation = value.debuggerModel().createRawLocationByScriptId(value.value.scriptId, value.value.lineNumber,
1565
+ value.value.columnNumber);
1566
+ const linkifiedLocation = rawLocation && linkifier ?
1567
+ linkifier.linkifyRawLocation(rawLocation, Platform.DevToolsPath.EmptyUrlString, 'value') :
1568
+ null;
1569
+ if (linkifiedLocation) {
1570
+ valueRef?.(linkifiedLocation);
1571
+ return html`${linkifiedLocation}`;
1572
+ }
1573
+ title = description || undefined;
1574
+ content = '<' + i18nString(UIStrings.unknown) + '>';
1575
+ } else if (isString) {
1576
+ const text = Platform.StringUtilities.escapeUnicodeAsText(JSON.stringify(description));
1577
+ const tooLong = description.length > maxRenderableStringLength;
1578
+ title = tooLong ? undefined : description;
1579
+ content = tooLong ? widget(ExpandableTextPropertyValue, {text}) : text;
1580
+ } else if (isTrustedType) {
1581
+ const text = `${className} "${description}"`;
1582
+ const tooLong = text.length > maxRenderableStringLength;
1583
+ title = tooLong ? undefined : text;
1584
+ content = tooLong ? widget(ExpandableTextPropertyValue, {text}) : renderTrustedType(description, className);
1585
+ } else if (isFunction) {
1586
+ content = ObjectPropertiesSection.valueElementForFunctionDescription(description);
1587
+ } else if (description.length > maxRenderableStringLength) {
1588
+ title = description;
1589
+ content = widget(ExpandableTextPropertyValue, {text: description});
1590
+ } else {
1591
+ title = description;
1592
+ const hasPreview = value.preview && showPreview;
1593
+ const previewContent = hasPreview ?
1594
+ new RemoteObjectPreviewFormatter().renderObjectPreview(value.preview, includeNullOrUndefined) :
1595
+ description;
1596
+ content = html`${previewContent}${
1597
+ isSyntheticProperty ? nothing : ObjectPropertiesSection.getMemoryIcon(value, variableName)}`;
1598
+ }
1599
+
1600
+ if (wasThrown) {
1601
+ return html`<span ${valueRef ? ref(valueRef) : nothing} class="error value">${
1602
+ uiI18n.getFormatLocalizedStringTemplate(str_, UIStrings.exceptionS, {
1603
+ PH1: html`<span
1604
+ class=${classes}
1605
+ title=${ifDefined(title)}
1606
+ @click=${isNode ? onNodeClick : nothing}
1607
+ @mousemove=${isNode ? onNodeMouseMove : nothing}
1608
+ @mouseleave=${isNode ? onNodeMouseLeave : nothing}>${content}</span>`,
1609
+ })}</span>`;
1610
+ }
1611
+ return html`<span
1612
+ ${valueRef ? ref(valueRef) : nothing}
1613
+ class=${classes}
1614
+ title=${ifDefined(title)}
1615
+ @click=${isNode ? onNodeClick : nothing}
1616
+ @mousemove=${isNode ? onNodeMouseMove : nothing}
1617
+ @mouseleave=${isNode ? onNodeMouseLeave : nothing}>${content}</span>`;
1618
+ }
1619
+
1620
+ export function defaultObjectPresentation(objectOrTree: SDK.RemoteObject.RemoteObject|ObjectTree,
1621
+ linkifier?: Components.Linkifier.Linkifier, skipProto?: boolean,
1622
+ readOnly?: boolean): LitTemplate {
1623
+ const objectTree = objectOrTree instanceof ObjectTree ? objectOrTree : new ObjectTree(objectOrTree, {
1624
+ readOnly: Boolean(readOnly),
1625
+ propertiesMode: ObjectPropertiesMode.OWN_AND_INTERNAL_AND_INHERITED,
1626
+ });
1627
+ const object = objectTree.object;
1628
+ const title = html`<span class="source-code"><style>${objectValueStyles}</style>${
1629
+ renderPropertyValue(object, /* wasThrown= */ false, /* showPreview= */ true)}</span>`;
1630
+ if (!object.hasChildren) {
1631
+ return title;
1632
+ }
1633
+ return renderObjectPropertiesSection(objectTree, title, linkifier, skipProto, !readOnly);
1634
+ }
1635
+
1528
1636
  /**
1529
1637
  * Number of initially visible children in an ObjectPropertyTreeElement.
1530
1638
  * Remaining children are shown as soon as requested via a show more properties button.
@@ -1584,7 +1692,7 @@ export const OBJECT_PROPERTY_DEFAULT_VIEW: ObjectPropertyView = (input, output,
1584
1692
  (entries ?? []).filter(e => e !== currentMatch && e.matchType === 'name').map(e => e.range.cssValue()).join(' ');
1585
1693
  const valueRanges =
1586
1694
  (entries ?? []).filter(e => e !== currentMatch && e.matchType === 'value').map(e => e.range.cssValue()).join(' ');
1587
- const value = (): LitTemplate|HTMLElement => {
1695
+ const value = (): LitTemplate => {
1588
1696
  const valueRef = ref(e => {
1589
1697
  output.valueElement = e;
1590
1698
  });
@@ -1593,11 +1701,11 @@ export const OBJECT_PROPERTY_DEFAULT_VIEW: ObjectPropertyView = (input, output,
1593
1701
  }
1594
1702
  if (property.value) {
1595
1703
  const showPreview = property.name !== '[[Prototype]]';
1596
- const value = ObjectPropertiesSection.createPropertyValueWithCustomSupport(
1597
- property.value, property.wasThrown, showPreview, input.linkifier, property.synthetic,
1598
- input.node.path /* variableName */, input.node.includeNullOrUndefinedValues);
1599
- output.valueElement = value;
1600
- return value;
1704
+ return renderPropertyValue(property.value, property.wasThrown, showPreview, input.linkifier, property.synthetic,
1705
+ input.node.path /* variableName */, input.node.includeNullOrUndefinedValues,
1706
+ /* useCustomPreview */ true, e => {
1707
+ output.valueElement = e;
1708
+ });
1601
1709
  }
1602
1710
  if (property.getter) {
1603
1711
  const getter = property.getter;
@@ -8,8 +8,13 @@
8
8
  opacity: 60%;
9
9
  }
10
10
 
11
+ :host {
12
+ display: block;
13
+ }
14
+
11
15
  .object-properties-section {
12
16
  padding: 0;
17
+ margin: 0;
13
18
  color: var(--sys-color-on-surface);
14
19
  display: flex;
15
20
  flex-direction: column;
@@ -89,14 +89,14 @@ export class CommandMenu {
89
89
  }
90
90
 
91
91
  static createSettingCommand<V>(setting: Common.Settings.Setting<V>, title: Common.UIString.LocalizedString, value: V,
92
- settingUIDescriptor?: SettingsUI.SettingUIRegistration.SettingUIDescriptor): Command {
93
- const uiDescriptor = settingUIDescriptor ?? SettingsUI.SettingUIRegistration.maybeResolve(setting.descriptor());
94
- const category = uiDescriptor?.category ?? setting.category();
95
- if (!category) {
92
+ settingUI?: SettingsUI.SettingUIRegistration.SettingUI): Command {
93
+ const ui = settingUI ?? SettingsUI.SettingUIRegistration.maybeResolve(setting.descriptor());
94
+ const category = ui?.category;
95
+ if (!category || !ui) {
96
96
  throw new Error(`Creating '${title}' setting command failed. Setting has no category.`);
97
97
  }
98
- const tags = uiDescriptor?.tags?.map(tag => tag()).join('\0') ?? setting.tags() ?? '';
99
- const reloadRequired = Boolean(uiDescriptor?.reloadRequired ?? setting.reloadRequired());
98
+ const tags = ui.tags;
99
+ const reloadRequired = ui.reloadRequired;
100
100
 
101
101
  return CommandMenu.createCommand({
102
102
  category: Common.Settings.getLocalizedSettingsCategory(category),
@@ -116,12 +116,8 @@ export class CommandMenu {
116
116
  i18nString(UIStrings.settingsChangedReloadDevTools));
117
117
  }
118
118
  },
119
- availableHandler,
119
+ availableHandler: () => setting.get() !== value,
120
120
  });
121
-
122
- function availableHandler(): boolean {
123
- return setting.get() !== value;
124
- }
125
121
  }
126
122
 
127
123
  static createActionCommand(options: ActionCommandOptions): Command {
@@ -212,8 +208,8 @@ export class CommandMenu {
212
208
  // Populate allowlisted settings.
213
209
  const settingsRegistrations = SettingsUI.SettingUIRegistration.getRegisteredSettings();
214
210
  for (const registeredSettingUI of settingsRegistrations) {
215
- const options = registeredSettingUI.uiDescriptor.options;
216
- if (!options || !registeredSettingUI.uiDescriptor.category) {
211
+ const settingUI = SettingsUI.SettingUIRegistration.resolve(registeredSettingUI.descriptor);
212
+ if (!settingUI.options.length || !settingUI.category) {
217
213
  continue;
218
214
  }
219
215
  let setting: Common.Settings.Setting<unknown>;
@@ -227,9 +223,8 @@ export class CommandMenu {
227
223
  } else {
228
224
  setting = Common.Settings.Settings.instance().resolve(registeredSettingUI.descriptor);
229
225
  }
230
- for (const pair of options) {
231
- this.#commands.push(
232
- CommandMenu.createSettingCommand(setting, pair.title(), pair.value, registeredSettingUI.uiDescriptor));
226
+ for (const option of settingUI.options) {
227
+ this.#commands.push(CommandMenu.createSettingCommand(setting, option.title, option.value, settingUI));
233
228
  }
234
229
  }
235
230
  }
@@ -44,16 +44,10 @@ export function createSettingCheckbox(
44
44
 
45
45
  export function renderSettingSelect(setting: Common.Settings.Setting<unknown>, subtitle?: string,
46
46
  disabled?: boolean): TemplateResult {
47
- const uiDescriptor = SettingUIRegistration.SettingUIRegistration.maybeResolve(setting.descriptor());
48
- const name = uiDescriptor?.title?.() ?? setting.title();
49
- const options = uiDescriptor?.options?.map(opt => ({
50
- value: opt.value,
51
- title: opt.title(),
52
- text: typeof opt.text === 'function' ? opt.text() : opt.text,
53
- raw: opt.raw,
54
- })) ??
55
- setting.options();
56
- const requiresReload = Boolean(uiDescriptor?.reloadRequired ?? setting.reloadRequired());
47
+ const uiDescriptor = SettingUIRegistration.SettingUIRegistration.resolve(setting.descriptor());
48
+ const name = uiDescriptor.title;
49
+ const options = uiDescriptor.options;
50
+ const requiresReload = uiDescriptor.reloadRequired;
57
51
  const controlId = UI.ARIAUtils.nextId('labelledControl');
58
52
  const reloadWarningRef = createRef<HTMLParagraphElement>();
59
53
 
@@ -115,8 +109,7 @@ export const renderControlForSetting = function(setting: Common.Settings.Setting
115
109
  case Common.Settings.SettingType.BOOLEAN: {
116
110
  const onchange = (): void => {
117
111
  const uiDescriptor = SettingUIRegistration.SettingUIRegistration.maybeResolve(setting.descriptor());
118
- const requiresReload = Boolean(uiDescriptor?.reloadRequired ?? setting.reloadRequired());
119
- if (requiresReload) {
112
+ if (uiDescriptor?.reloadRequired) {
120
113
  UI.InspectorView.InspectorView.instance().displayReloadRequiredWarning(
121
114
  i18nString(UIStrings.settingsChangedReloadDevTools));
122
115
  }
@@ -94,6 +94,8 @@ export class JSONView extends UI.Widget.VBox implements UI.SearchableView.Search
94
94
  if (this.objectTree) {
95
95
  this.objectTree.removeEventListener(ObjectUI.ObjectPropertiesSection.ObjectTreeNodeBase.Events.CHILDREN_CHANGED,
96
96
  this.#onChildrenChanged, this);
97
+ this.objectTree.removeEventListener(ObjectUI.ObjectPropertiesSection.ObjectTreeNodeBase.Events.EXPANDED_CHANGED,
98
+ this.#onChildrenChanged, this);
97
99
  }
98
100
  this.#parsedJSON = parsedJSON;
99
101
  this.objectTree = null;
@@ -187,6 +189,8 @@ export class JSONView extends UI.Widget.VBox implements UI.SearchableView.Search
187
189
  }
188
190
  this.objectTree.addEventListener(ObjectUI.ObjectPropertiesSection.ObjectTreeNodeBase.Events.CHILDREN_CHANGED,
189
191
  this.#onChildrenChanged, this);
192
+ this.objectTree.addEventListener(ObjectUI.ObjectPropertiesSection.ObjectTreeNodeBase.Events.EXPANDED_CHANGED,
193
+ this.#onChildrenChanged, this);
190
194
  }
191
195
 
192
196
  #onChildrenChanged(): void {
@@ -222,7 +226,8 @@ export class JSONView extends UI.Widget.VBox implements UI.SearchableView.Search
222
226
  }
223
227
  }
224
228
 
225
- performSearch(searchConfig: UI.SearchableView.SearchConfig, shouldJump: boolean, jumpBackwards?: boolean): void {
229
+ async performSearch(searchConfig: UI.SearchableView.SearchConfig, shouldJump: boolean,
230
+ jumpBackwards?: boolean): Promise<void> {
226
231
  this.initialize();
227
232
  this.onSearchCanceled();
228
233
  const searchRegex = searchConfig.toSearchRegex(true).regex;
@@ -230,6 +235,8 @@ export class JSONView extends UI.Widget.VBox implements UI.SearchableView.Search
230
235
  return;
231
236
  }
232
237
 
238
+ await this.objectTree.populateChildrenIfNeeded();
239
+
233
240
  this.search.search(this.objectTree, jumpBackwards ?? false, (node, closeTag) => {
234
241
  if (closeTag || !searchRegex) {
235
242
  return [];