chrome-devtools-frontend 1.0.1544076 → 1.0.1547147

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 (178) hide show
  1. package/config/typescript/tsconfig.eslint.json +1 -0
  2. package/docs/styleguide/ux/styles.md +1 -1
  3. package/eslint.config.mjs +1 -1
  4. package/front_end/Images/src/arrow-down.svg +8 -1
  5. package/front_end/Images/src/arrow-up.svg +8 -1
  6. package/front_end/core/common/ParsedURL.ts +1 -1
  7. package/front_end/core/common/common.ts +0 -2
  8. package/front_end/core/host/AidaClient.ts +1 -1
  9. package/front_end/core/host/InspectorFrontendHostAPI.ts +0 -1
  10. package/front_end/core/host/UserMetrics.ts +0 -5
  11. package/front_end/core/platform/HostRuntime.ts +18 -0
  12. package/front_end/core/platform/KeyboardUtilities.ts +2 -2
  13. package/front_end/core/platform/StringUtilities.ts +1 -1
  14. package/front_end/core/platform/api/HostRuntime.ts +20 -0
  15. package/front_end/core/platform/api/api.ts +7 -0
  16. package/front_end/core/platform/browser/HostRuntime.ts +14 -0
  17. package/front_end/core/platform/browser/browser.ts +7 -0
  18. package/front_end/core/platform/node/HostRuntime.ts +13 -0
  19. package/front_end/core/platform/node/node.ts +7 -0
  20. package/front_end/core/platform/platform.ts +2 -2
  21. package/front_end/core/protocol_client/CDPConnection.ts +3 -3
  22. package/front_end/core/protocol_client/DevToolsCDPConnection.ts +2 -1
  23. package/front_end/core/sdk/CSSMetadata.ts +17 -5
  24. package/front_end/core/sdk/NetworkManager.ts +6 -8
  25. package/front_end/core/sdk/NetworkRequest.ts +4 -0
  26. package/front_end/core/sdk/SDKModel.ts +4 -2
  27. package/front_end/core/sdk/SourceMapScopesInfo.ts +141 -23
  28. package/front_end/core/sdk/Target.ts +5 -14
  29. package/front_end/core/sdk/TargetManager.ts +39 -18
  30. package/front_end/core/sdk/sdk-meta.ts +62 -0
  31. package/front_end/devtools_compatibility.js +0 -1
  32. package/front_end/entrypoints/main/MainImpl.ts +2 -2
  33. package/front_end/foundation/Universe.ts +2 -2
  34. package/front_end/generated/Deprecation.ts +11 -0
  35. package/front_end/generated/InspectorBackendCommands.ts +3 -6
  36. package/front_end/generated/SupportedCSSProperties.js +4 -25
  37. package/front_end/generated/protocol-mapping.d.ts +0 -15
  38. package/front_end/generated/protocol-proxy-api.d.ts +0 -11
  39. package/front_end/generated/protocol.ts +5 -36
  40. package/front_end/models/ai_assistance/AiConversation.ts +188 -0
  41. package/front_end/models/ai_assistance/AiHistoryStorage.ts +1 -172
  42. package/front_end/models/ai_assistance/ConversationHandler.ts +5 -5
  43. package/front_end/models/ai_assistance/agents/AiAgent.ts +1 -3
  44. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +6 -2
  45. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +1 -1
  46. package/front_end/models/ai_assistance/agents/StylingAgent.ts +3 -9
  47. package/front_end/models/ai_assistance/ai_assistance.ts +2 -0
  48. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +313 -313
  49. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +8 -6
  50. package/front_end/models/ai_assistance/performance/AICallTree.snapshot.txt +33 -33
  51. package/front_end/models/ai_assistance/performance/AICallTree.ts +9 -3
  52. package/front_end/models/bindings/CSSWorkspaceBinding.ts +5 -3
  53. package/front_end/models/bindings/SASSSourceMapping.ts +6 -4
  54. package/front_end/models/cpu_profile/CPUProfileDataModel.ts +10 -7
  55. package/front_end/models/crux-manager/CrUXManager.ts +7 -4
  56. package/front_end/models/issues_manager/GenericIssue.ts +12 -9
  57. package/front_end/models/javascript_metadata/NativeFunctions.js +4 -0
  58. package/front_end/models/trace/handlers/SamplesHandler.ts +3 -0
  59. package/front_end/models/trace/helpers/Trace.ts +13 -0
  60. package/front_end/models/trace/types/TraceEvents.ts +2 -1
  61. package/front_end/models/trace_source_maps_resolver/SourceMapsResolver.ts +29 -0
  62. package/front_end/models/workspace/IgnoreListManager.ts +1 -2
  63. package/front_end/models/workspace/UISourceCode.ts +50 -0
  64. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +11 -10
  65. package/front_end/panels/ai_assistance/ai_assistance-meta.ts +8 -0
  66. package/front_end/panels/ai_assistance/components/ChatView.ts +2 -2
  67. package/front_end/panels/ai_assistance/components/UserActionRow.ts +2 -1
  68. package/front_end/panels/animation/AnimationTimeline.ts +0 -8
  69. package/front_end/panels/application/ApplicationPanelSidebar.ts +6 -7
  70. package/front_end/panels/application/{components/FrameDetailsView.ts → FrameDetailsView.ts} +140 -171
  71. package/front_end/panels/application/{components/OriginTrialTreeView.ts → OriginTrialTreeView.ts} +9 -9
  72. package/front_end/panels/application/application.ts +4 -0
  73. package/front_end/panels/application/components/StackTrace.ts +89 -88
  74. package/front_end/panels/application/components/components.ts +2 -4
  75. package/front_end/panels/application/{components/frameDetailsReportView.css → frameDetailsReportView.css} +5 -1
  76. package/front_end/panels/common/AiCodeGenerationTeaser.ts +80 -0
  77. package/front_end/panels/common/BadgeNotification.ts +2 -1
  78. package/front_end/panels/common/DOMLinkifier.ts +7 -2
  79. package/front_end/panels/common/GdpSignUpDialog.ts +2 -1
  80. package/front_end/panels/common/common.ts +2 -1
  81. package/front_end/panels/console/ConsolePrompt.ts +3 -1
  82. package/front_end/panels/console/ConsoleViewport.ts +1 -2
  83. package/front_end/panels/elements/ElementIssueUtils.ts +2 -2
  84. package/front_end/panels/elements/ElementStatePaneWidget.ts +2 -1
  85. package/front_end/panels/elements/StylePropertiesSection.ts +1 -1
  86. package/front_end/panels/elements/StylePropertyTreeElement.ts +23 -19
  87. package/front_end/panels/elements/StylesSidebarPane.ts +1 -1
  88. package/front_end/panels/elements/cssValueTraceView.css +1 -1
  89. package/front_end/panels/elements/elements-meta.ts +1 -22
  90. package/front_end/panels/explain/components/ConsoleInsight.ts +44 -57
  91. package/front_end/panels/explain/components/consoleInsight.css +46 -1
  92. package/front_end/panels/layer_viewer/LayerTreeOutline.ts +1 -2
  93. package/front_end/panels/lighthouse/LighthouseProtocolService.ts +3 -6
  94. package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +19 -0
  95. package/front_end/panels/network/RequestConditionsDrawer.ts +54 -24
  96. package/front_end/panels/network/networkLogView.css +11 -0
  97. package/front_end/panels/network/networkTimingTable.css +8 -6
  98. package/front_end/panels/network/requestConditionsDrawer.css +10 -1
  99. package/front_end/panels/profiler/ProfilesPanel.ts +1 -2
  100. package/front_end/panels/settings/FrameworkIgnoreListSettingsTab.ts +2 -1
  101. package/front_end/panels/settings/KeybindsSettingsTab.ts +20 -21
  102. package/front_end/panels/settings/SettingsScreen.ts +3 -2
  103. package/front_end/panels/sources/CoveragePlugin.ts +5 -5
  104. package/front_end/panels/sources/Plugin.ts +1 -1
  105. package/front_end/panels/sources/ProfilePlugin.ts +22 -14
  106. package/front_end/panels/sources/UISourceCodeFrame.ts +2 -1
  107. package/front_end/panels/sources/sources-meta.ts +0 -62
  108. package/front_end/panels/timeline/README.md +1 -9
  109. package/front_end/panels/timeline/ThreadAppender.ts +0 -7
  110. package/front_end/panels/timeline/TimelinePanel.ts +1 -1
  111. package/front_end/panels/timeline/TimelineUIUtils.ts +2 -0
  112. package/front_end/panels/timeline/components/ExportTraceOptions.ts +15 -1
  113. package/front_end/panels/timeline/components/LiveMetricsView.ts +51 -6
  114. package/front_end/panels/timeline/components/MetricCard.ts +2 -2
  115. package/front_end/panels/timeline/components/exportTraceOptions.css +11 -2
  116. package/front_end/panels/timeline/components/insights/NodeLink.ts +2 -3
  117. package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +2 -1
  118. package/front_end/panels/timeline/timeline-meta.ts +0 -10
  119. package/front_end/panels/timeline/timeline.ts +0 -2
  120. package/front_end/panels/whats_new/ReleaseNoteView.ts +2 -1
  121. package/front_end/panels/whats_new/WhatsNewImpl.ts +3 -2
  122. package/front_end/third_party/chromium/README.chromium +1 -1
  123. package/front_end/tsconfig.json +1 -0
  124. package/front_end/ui/components/buttons/Button.docs.ts +6 -5
  125. package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +1 -0
  126. package/front_end/ui/components/snackbars/Snackbars.docs.ts +1 -1
  127. package/front_end/ui/components/spinners/Spinners.docs.ts +1 -1
  128. package/front_end/ui/components/survey_link/SurveyLink.docs.ts +2 -1
  129. package/front_end/ui/components/switch/Switch.docs.ts +1 -1
  130. package/front_end/ui/components/tooltips/Tooltip.docs.ts +3 -3
  131. package/front_end/ui/helpers/OpenInNewTab.ts +87 -0
  132. package/front_end/ui/helpers/helpers.ts +5 -0
  133. package/front_end/ui/legacy/ARIAUtils.ts +2 -2
  134. package/front_end/ui/legacy/ActionRegistration.ts +11 -0
  135. package/front_end/ui/legacy/ContextMenu.docs.ts +12 -11
  136. package/front_end/ui/legacy/RadioButton.docs.ts +1 -1
  137. package/front_end/ui/legacy/SelectMenu.docs.ts +1 -1
  138. package/front_end/ui/legacy/Slider.docs.ts +1 -1
  139. package/front_end/ui/legacy/SoftDropDown.ts +2 -2
  140. package/front_end/ui/legacy/TextPrompt.ts +3 -2
  141. package/front_end/ui/legacy/Treeoutline.ts +2 -1
  142. package/front_end/ui/legacy/UIUtils.ts +11 -43
  143. package/front_end/ui/legacy/Widget.ts +3 -2
  144. package/front_end/ui/legacy/XLink.ts +4 -4
  145. package/front_end/ui/legacy/components/color_picker/ContrastDetails.ts +2 -1
  146. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +2 -2
  147. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +144 -143
  148. package/front_end/ui/legacy/components/perf_ui/LineLevelProfile.ts +62 -39
  149. package/front_end/ui/legacy/components/perf_ui/OverviewGrid.ts +1 -1
  150. package/front_end/ui/legacy/components/perf_ui/TimelineGrid.ts +2 -2
  151. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +2 -7
  152. package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +1 -2
  153. package/front_end/ui/legacy/components/utils/Linkifier.ts +2 -1
  154. package/front_end/ui/legacy/inspectorCommon.css +2 -2
  155. package/front_end/ui/legacy/legacy.ts +2 -0
  156. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
  157. package/mcp/tsconfig.json +16 -0
  158. package/package.json +2 -2
  159. package/front_end/core/common/Linkifier.ts +0 -55
  160. package/front_end/panels/explain/components/consoleInsightSourcesList.css +0 -51
  161. package/front_end/panels/timeline/CLSLinkifier.ts +0 -58
  162. package/front_end/ui/components/docs/README.md +0 -6
  163. package/front_end/ui/components/docs/building-ui-documentation/ComponentEvents.md +0 -54
  164. package/front_end/ui/components/docs/building-ui-documentation/ComponentPerformance.md +0 -136
  165. package/front_end/ui/components/docs/building-ui-documentation/CreatingComponents.md +0 -242
  166. package/front_end/ui/components/docs/building-ui-documentation/README.md +0 -23
  167. package/front_end/ui/components/docs/building-ui-documentation/StylingComponents.md +0 -66
  168. package/front_end/ui/components/docs/building-ui-documentation/TestingComponents.md +0 -111
  169. package/front_end/ui/components/docs/component_docs.ts +0 -24
  170. package/front_end/ui/components/docs/component_docs_styles.css +0 -53
  171. package/front_end/ui/components/docs/create_breadcrumbs.ts +0 -44
  172. package/front_end/ui/components/docs/slider/basic.html +0 -20
  173. package/front_end/ui/components/docs/switch/basic.html +0 -20
  174. /package/front_end/models/issues_manager/descriptions/{genericFormAriaLabelledByToNonExistingId.md → genericFormAriaLabelledByToNonExistingIdError.md} +0 -0
  175. /package/front_end/models/issues_manager/descriptions/{genericFormLabelHasNeitherForNorNestedInput.md → genericFormLabelHasNeitherForNorNestedInputError.md} +0 -0
  176. /package/front_end/panels/application/{components/originTrialTokenRows.css → originTrialTokenRows.css} +0 -0
  177. /package/front_end/panels/application/{components/originTrialTreeView.css → originTrialTreeView.css} +0 -0
  178. /package/front_end/{core/platform → ui/legacy}/DOMUtilities.ts +0 -0
@@ -4,6 +4,7 @@
4
4
 
5
5
  import * as Host from '../../core/host/host.js';
6
6
  import * as Platform from '../../core/platform/platform.js';
7
+ import * as UIHelpers from '../helpers/helpers.js';
7
8
  import * as VisualLogging from '../visual_logging/visual_logging.js';
8
9
 
9
10
  import * as ARIAUtils from './ARIAUtils.js';
@@ -13,7 +14,6 @@ import {Tooltip} from './Tooltip.js';
13
14
  import {
14
15
  copyLinkAddressLabel,
15
16
  MaxLengthForDisplayedURLs,
16
- openInNewTab,
17
17
  openLinkExternallyLabel,
18
18
  } from './UIUtils.js';
19
19
  import {XElement} from './XElement.js';
@@ -54,14 +54,14 @@ export class XLink extends XElement {
54
54
  this.onClick = (event: Event) => {
55
55
  event.consume(true);
56
56
  if (this.#href) {
57
- openInNewTab(this.#href);
57
+ UIHelpers.openInNewTab(this.#href);
58
58
  }
59
59
  };
60
60
  this.onKeyDown = (event: KeyboardEvent) => {
61
61
  if (Platform.KeyboardUtilities.isEnterOrSpaceKey(event)) {
62
62
  event.consume(true);
63
63
  if (this.#href) {
64
- openInNewTab(this.#href);
64
+ UIHelpers.openInNewTab(this.#href);
65
65
  }
66
66
  }
67
67
  };
@@ -140,7 +140,7 @@ export class ContextMenuProvider implements Provider<Node> {
140
140
  const node: XLink = targetNode;
141
141
  contextMenu.revealSection().appendItem(openLinkExternallyLabel(), () => {
142
142
  if (node.href) {
143
- openInNewTab(node.href);
143
+ UIHelpers.openInNewTab(node.href);
144
144
  }
145
145
  }, {jslogContext: 'open-in-new-tab'});
146
146
  contextMenu.revealSection().appendItem(copyLinkAddressLabel(), () => {
@@ -11,6 +11,7 @@ import * as i18n from '../../../../core/i18n/i18n.js';
11
11
  import * as Platform from '../../../../core/platform/platform.js';
12
12
  import * as Root from '../../../../core/root/root.js';
13
13
  import * as IconButton from '../../../../ui/components/icon_button/icon_button.js';
14
+ import * as UIHelpers from '../../../helpers/helpers.js';
14
15
  import * as UI from '../../legacy.js';
15
16
 
16
17
  import {type ContrastInfo, Events as ContrastInfoEvents} from './ContrastInfo.js';
@@ -363,7 +364,7 @@ export class ContrastDetails extends Common.ObjectWrapper.ObjectWrapper<EventTyp
363
364
  }
364
365
 
365
366
  private static showHelp(): void {
366
- UI.UIUtils.openInNewTab('https://web.dev/color-and-contrast-accessibility/');
367
+ UIHelpers.openInNewTab('https://web.dev/color-and-contrast-accessibility/');
367
368
  }
368
369
 
369
370
  setVisible(visible: boolean): void {
@@ -368,7 +368,7 @@ export class DataGridImpl<T> extends Common.ObjectWrapper.ObjectWrapper<EventTyp
368
368
 
369
369
  announceSelectedGridNode(): void {
370
370
  // Only alert if the datagrid has focus
371
- if (this.element === Platform.DOMUtilities.deepActiveElement(this.element.ownerDocument) &&
371
+ if (this.element === UI.DOMUtilities.deepActiveElement(this.element.ownerDocument) &&
372
372
  this.selectedNode?.existingElement()) {
373
373
  // Update the expand/collapse state for the current selected node
374
374
  let expandText;
@@ -1237,7 +1237,7 @@ export class DataGridImpl<T> extends Common.ObjectWrapper.ObjectWrapper<EventTyp
1237
1237
  nextSelectedNode.select();
1238
1238
  }
1239
1239
 
1240
- const activeElement = (Platform.DOMUtilities.deepActiveElement(this.element.ownerDocument) as HTMLElement | null);
1240
+ const activeElement = (UI.DOMUtilities.deepActiveElement(this.element.ownerDocument) as HTMLElement | null);
1241
1241
  if (handled && this.element !== activeElement && !this.element.contains(activeElement)) {
1242
1242
  // crbug.com/1005449, crbug.com/1329956
1243
1243
  // navigational or delete keys pressed but current DataGrid panel has lost focus;
@@ -49,7 +49,7 @@ import objectPropertiesSectionStyles from './objectPropertiesSection.css.js';
49
49
  import objectValueStyles from './objectValue.css.js';
50
50
  import {RemoteObjectPreviewFormatter, renderNodeTitle} from './RemoteObjectPreviewFormatter.js';
51
51
 
52
- const {repeat, ifDefined} = Directives;
52
+ const {ref, repeat, ifDefined, classMap} = Directives;
53
53
  const UIStrings = {
54
54
  /**
55
55
  * @description Text in Object Properties Section
@@ -874,45 +874,116 @@ export class RootElement extends UI.TreeOutline.TreeElement {
874
874
  export const InitialVisibleChildrenLimit = 200;
875
875
 
876
876
  export interface TreeElementViewInput {
877
+ startEditing(): unknown;
878
+ invokeGetter(getter: SDK.RemoteObject.RemoteObject): unknown;
877
879
  onAutoComplete(expression: string, filter: string, force: boolean): unknown;
880
+ linkifier: Components.Linkifier.Linkifier|undefined;
878
881
  completions: string[];
879
- expandedValueElement: HTMLElement|undefined;
880
882
  expanded: boolean;
881
883
  editing: boolean;
882
884
  editingEnded(): unknown;
883
885
  editingCommitted(detail: string): unknown;
884
886
  node: ObjectTreeNode;
885
- nameElement: HTMLElement;
886
- valueElement: HTMLElement;
887
887
  }
888
- type TreeElementView = (input: TreeElementViewInput, output: object, target: HTMLElement) => void;
888
+ interface TreeElementViewOutput {
889
+ valueElement: Element|undefined;
890
+ nameElement: Element|undefined;
891
+ }
892
+ type TreeElementView = (input: TreeElementViewInput, output: TreeElementViewOutput, target: HTMLElement) => void;
889
893
  export const TREE_ELEMENT_DEFAULT_VIEW: TreeElementView = (input, output, target) => {
890
- const isInternalEntries = input.node.property.synthetic && input.node.name === '[[Entries]]';
891
- if (isInternalEntries) {
892
- render(html`<span class=name-and-value>${input.nameElement}</span>`, target);
893
- } else {
894
- const completionsId = `completions-${input.node.parent?.object?.objectId?.replaceAll('.', '-')}-${input.node.name}`;
895
- const onAutoComplete = async(e: UI.TextPrompt.TextPromptElement.BeforeAutoCompleteEvent): Promise<void> => {
896
- if (!(e.target instanceof UI.TextPrompt.TextPromptElement)) {
897
- return;
898
- }
899
- input.onAutoComplete(e.detail.expression, e.detail.filter, e.detail.force);
900
- };
901
- // clang-format off
902
- render(
903
- html`<span class=name-and-value>${input.nameElement}<span class='separator'>: </span><devtools-prompt
904
- @commit=${(e: UI.TextPrompt.TextPromptElement.CommitEvent) => input.editingCommitted(e.detail)}
905
- @cancel=${() => input.editingEnded()}
906
- @beforeautocomplete=${onAutoComplete}
907
- completions=${completionsId}
908
- placeholder=${i18nString(UIStrings.stringIsTooLargeToEdit)}
909
- ?editing=${input.editing}>
910
- ${input.expanded && input.expandedValueElement || input.valueElement}
911
- <datalist id=${completionsId}>${repeat(input.completions, c => html`<option>${c}</option>`)}</datalist>
912
- </devtools-prompt></span><span>`,
913
- target);
914
- // clang-format on
915
- }
894
+ const {property} = input.node;
895
+ const isInternalEntries = property.synthetic && input.node.name === '[[Entries]]';
896
+ const completionsId = `completions-${input.node.parent?.object?.objectId?.replaceAll('.', '-')}-${input.node.name}`;
897
+ const onAutoComplete = async(e: UI.TextPrompt.TextPromptElement.BeforeAutoCompleteEvent): Promise<void> => {
898
+ if (!(e.target instanceof UI.TextPrompt.TextPromptElement)) {
899
+ return;
900
+ }
901
+ input.onAutoComplete(e.detail.expression, e.detail.filter, e.detail.force);
902
+ };
903
+ const nameClasses = classMap({
904
+ name: true,
905
+ 'object-properties-section-dimmed': !property.enumerable,
906
+ 'own-property': property.isOwn,
907
+ 'synthetic-property': property.synthetic,
908
+ });
909
+ const quotedName =
910
+ /^\s|\s$|^$|\n/.test(property.name) ? `"${property.name.replace(/\n/g, '\u21B5')}"` : property.name;
911
+ const isExpandable = !isInternalEntries && property.value && !property.wasThrown && property.value.hasChildren &&
912
+ !property.value.customPreview() && property.value.subtype !== 'node' && property.value.type !== 'function' &&
913
+ (property.value.type !== 'object' || property.value.preview);
914
+
915
+ const value = (): LitTemplate|HTMLElement => {
916
+ const valueRef = ref(e => {
917
+ output.valueElement = e;
918
+ });
919
+ if (isInternalEntries) {
920
+ return html`<span ${valueRef} class=value></span>`;
921
+ }
922
+ if (property.value) {
923
+ const showPreview = property.name !== '[[Prototype]]';
924
+ const value = ObjectPropertiesSection.createPropertyValueWithCustomSupport(
925
+ property.value, property.wasThrown, showPreview, input.linkifier, property.synthetic,
926
+ input.node.path /* variableName */);
927
+ output.valueElement = value;
928
+ return value;
929
+ }
930
+ if (property.getter) {
931
+ const getter = property.getter;
932
+ const invokeGetter = (event: Event): void => {
933
+ event.consume();
934
+ input.invokeGetter(getter);
935
+ };
936
+ return html`<span ${valueRef}><span
937
+ class=object-value-calculate-value-button
938
+ title=${i18nString(UIStrings.invokePropertyGetter)}
939
+ @click=${invokeGetter}
940
+ >${i18nString(UIStrings.dots)}</span></span>`;
941
+ }
942
+ return html`<span ${valueRef}
943
+ class=object-value-unavailable
944
+ title=${i18nString(UIStrings.valueNotAccessibleToTheDebugger)}>${
945
+ i18nString(UIStrings.valueUnavailable)}</span>`;
946
+ };
947
+
948
+ const onDblClick = (event: Event): void => {
949
+ event.consume(true);
950
+ if (property.value && !property.value.customPreview() && (property.writable || property.setter)) {
951
+ input.startEditing();
952
+ }
953
+ };
954
+
955
+ // clang-format off
956
+ render(
957
+ html`<span class=name-and-value><span
958
+ ${ref(e => { output.nameElement = e; })}
959
+ class=${nameClasses}
960
+ title=${input.node.path}>${property.private ?
961
+ html`<span class="private-property-hash">${property.name[0]}</span>${
962
+ property.name.substring(1)}</span>` : quotedName}</span>${
963
+ isInternalEntries ? nothing :
964
+ html`<span class='separator'>: </span><devtools-prompt
965
+ @commit=${(e: UI.TextPrompt.TextPromptElement.CommitEvent) => input.editingCommitted(e.detail)}
966
+ @cancel=${() => input.editingEnded()}
967
+ @beforeautocomplete=${onAutoComplete}
968
+ @dblclick=${onDblClick}
969
+ completions=${completionsId}
970
+ placeholder=${i18nString(UIStrings.stringIsTooLargeToEdit)}
971
+ ?editing=${input.editing}>
972
+ ${input.expanded && isExpandable && property.value ?
973
+ html`<span
974
+ class="value object-value-${property.value.subtype || property.value.type}"
975
+ title=${ifDefined(property.value.description)}>${
976
+ property.value.description === 'Object' ? '' :
977
+ Platform.StringUtilities.trimMiddle(property.value.description ?? '',
978
+ maxRenderableStringLength)}${
979
+ property.synthetic ? nothing :
980
+ ObjectPropertiesSection.getMemoryIcon(property.value)}</span>` :
981
+ value()
982
+ }
983
+ <datalist id=${completionsId}>${repeat(input.completions, c => html`<option>${c}</option>`)}</datalist>
984
+ </devtools-prompt></span>`}</span>`,
985
+ target);
986
+ // clang-format on
916
987
  };
917
988
  export class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
918
989
  property: ObjectTreeNode;
@@ -920,15 +991,13 @@ export class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
920
991
  private highlightChanges: UI.UIUtils.HighlightChange[];
921
992
  private linkifier: Components.Linkifier.Linkifier|undefined;
922
993
  private readonly maxNumPropertiesToShow: number;
923
- nameElement!: HTMLElement;
924
- valueElement!: HTMLElement;
925
994
  readOnly!: boolean;
926
995
  private prompt!: ObjectPropertyPrompt|undefined;
927
- private editableDiv!: HTMLElement;
928
- expandedValueElement?: HTMLElement;
929
996
  #editing = false;
930
997
  readonly #view: TreeElementView;
931
998
  #completions: string[] = [];
999
+ #nameElement: Element|undefined;
1000
+ #valueElement: Element|undefined;
932
1001
  constructor(property: ObjectTreeNode, linkifier?: Components.Linkifier.Linkifier, view = TREE_ELEMENT_DEFAULT_VIEW) {
933
1002
  // Pass an empty title, the title gets made later in onattach.
934
1003
  super();
@@ -1071,6 +1140,10 @@ export class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
1071
1140
  return rootElement;
1072
1141
  }
1073
1142
 
1143
+ get nameElement(): Element|undefined {
1144
+ return this.#nameElement;
1145
+ }
1146
+
1074
1147
  setSearchRegex(regex: RegExp, additionalCssClassName?: string): boolean {
1075
1148
  let cssClasses = UI.UIUtils.highlightedSearchResultClassName;
1076
1149
  if (additionalCssClassName) {
@@ -1078,11 +1151,13 @@ export class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
1078
1151
  }
1079
1152
  this.revertHighlightChanges();
1080
1153
 
1081
- this.applySearch(regex, this.nameElement, cssClasses);
1154
+ if (this.#nameElement) {
1155
+ this.applySearch(regex, this.#nameElement, cssClasses);
1156
+ }
1082
1157
  if (this.property.object) {
1083
1158
  const valueType = this.property.object.type;
1084
- if (valueType !== 'object') {
1085
- this.applySearch(regex, this.valueElement, cssClasses);
1159
+ if (valueType !== 'object' && this.#valueElement) {
1160
+ this.applySearch(regex, this.#valueElement, cssClasses);
1086
1161
  }
1087
1162
  }
1088
1163
 
@@ -1144,17 +1219,6 @@ export class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
1144
1219
  }
1145
1220
  }
1146
1221
 
1147
- override ondblclick(event: Event): boolean {
1148
- const target = (event.target as HTMLElement);
1149
- const inEditableElement = target.isSelfOrDescendant(this.valueElement) ||
1150
- (this.expandedValueElement && target.isSelfOrDescendant(this.expandedValueElement));
1151
- if (this.property.object && !this.property.object.customPreview() && inEditableElement &&
1152
- (this.property.property.writable || this.property.property.setter)) {
1153
- this.startEditing();
1154
- }
1155
- return false;
1156
- }
1157
-
1158
1222
  override onenter(): boolean {
1159
1223
  if (this.property.object && !this.property.object.customPreview() &&
1160
1224
  (this.property.property.writable || this.property.property.setter)) {
@@ -1165,7 +1229,7 @@ export class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
1165
1229
  }
1166
1230
 
1167
1231
  override onattach(): void {
1168
- this.update();
1232
+ this.performUpdate();
1169
1233
  this.updateExpandable();
1170
1234
  }
1171
1235
 
@@ -1177,87 +1241,6 @@ export class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
1177
1241
  this.performUpdate();
1178
1242
  }
1179
1243
 
1180
- private createExpandedValueElement(value: SDK.RemoteObject.RemoteObject, isSyntheticProperty: boolean): HTMLElement
1181
- |undefined {
1182
- const needsAlternateValue = value.hasChildren && !value.customPreview() && value.subtype !== 'node' &&
1183
- value.type !== 'function' && (value.type !== 'object' || value.preview);
1184
- if (!needsAlternateValue) {
1185
- return undefined;
1186
- }
1187
-
1188
- const valueElement = document.createElement('span');
1189
- valueElement.classList.add('value');
1190
- if (value.description === 'Object') {
1191
- valueElement.textContent = '';
1192
- } else {
1193
- valueElement.setTextContentTruncatedIfNeeded(value.description || '');
1194
- }
1195
- valueElement.classList.add('object-value-' + (value.subtype || value.type));
1196
- UI.Tooltip.Tooltip.install(valueElement, value.description || '');
1197
- if (!isSyntheticProperty) {
1198
- ObjectPropertiesSection.appendMemoryIcon(valueElement, value);
1199
- }
1200
- return valueElement;
1201
- }
1202
-
1203
- update(): void {
1204
- this.nameElement =
1205
- (ObjectPropertiesSection.createNameElement(this.property.name, this.property.property.private) as HTMLElement);
1206
- if (!this.property.property.enumerable) {
1207
- this.nameElement.classList.add('object-properties-section-dimmed');
1208
- }
1209
- if (this.property.property.isOwn) {
1210
- this.nameElement.classList.add('own-property');
1211
- }
1212
- if (this.property.property.synthetic) {
1213
- this.nameElement.classList.add('synthetic-property');
1214
- }
1215
- this.nameElement.title = this.property.path;
1216
-
1217
- const isInternalEntries = this.property.property.synthetic && this.property.name === '[[Entries]]';
1218
- if (isInternalEntries) {
1219
- this.valueElement = document.createElement('span');
1220
- this.valueElement.classList.add('value');
1221
- } else if (this.property.object) {
1222
- const showPreview = this.property.name !== '[[Prototype]]';
1223
- this.valueElement = ObjectPropertiesSection.createPropertyValueWithCustomSupport(
1224
- this.property.object, this.property.property.wasThrown, showPreview, this.linkifier,
1225
- this.property.property.synthetic, this.property.path /* variableName */);
1226
- } else if (this.property.property.getter) {
1227
- this.valueElement = document.createElement('span');
1228
- const element = this.valueElement.createChild('span');
1229
- element.textContent = i18nString(UIStrings.dots);
1230
- element.classList.add('object-value-calculate-value-button');
1231
- UI.Tooltip.Tooltip.install(element, i18nString(UIStrings.invokePropertyGetter));
1232
- const getter = this.property.property.getter;
1233
- element.addEventListener('click', (event: Event) => {
1234
- event.consume();
1235
- const invokeGetter = `
1236
- function invokeGetter(getter) {
1237
- return Reflect.apply(getter, this, []);
1238
- }`;
1239
- // Also passing a string instead of a Function to avoid coverage implementation messing with it.
1240
- void this.property.parent
1241
- ?.object
1242
- // @ts-expect-error No way to teach TypeScript to preserve the Function-ness of `getter`.
1243
- ?.callFunction(invokeGetter, [SDK.RemoteObject.RemoteObject.toCallArgument(getter)])
1244
- .then(this.onInvokeGetterClick.bind(this));
1245
- }, false);
1246
- } else {
1247
- this.valueElement = document.createElement('span');
1248
- this.valueElement.classList.add('object-value-unavailable');
1249
- this.valueElement.textContent = i18nString(UIStrings.valueUnavailable);
1250
- UI.Tooltip.Tooltip.install(this.valueElement, i18nString(UIStrings.valueNotAccessibleToTheDebugger));
1251
- }
1252
-
1253
- const valueText = this.valueElement.textContent;
1254
- if (this.property.object && valueText && !this.property.property.wasThrown) {
1255
- this.expandedValueElement =
1256
- this.createExpandedValueElement(this.property.object, this.property.property.synthetic);
1257
- }
1258
- this.performUpdate();
1259
- }
1260
-
1261
1244
  async #updateCompletions(expression: string, filter: string, force: boolean): Promise<void> {
1262
1245
  const suggestions = await TextEditor.JavaScript.completeInContext(expression, filter, force);
1263
1246
  this.#completions = suggestions.map(v => v.text);
@@ -1266,18 +1249,27 @@ export class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
1266
1249
 
1267
1250
  performUpdate(): void {
1268
1251
  const input: TreeElementViewInput = {
1269
- expandedValueElement: this.expandedValueElement,
1270
1252
  expanded: this.expanded,
1271
1253
  editing: this.#editing,
1272
1254
  editingEnded: this.editingEnded.bind(this),
1273
1255
  editingCommitted: this.editingCommitted.bind(this),
1274
1256
  node: this.property,
1275
- nameElement: this.nameElement,
1276
- valueElement: this.valueElement,
1257
+ linkifier: this.linkifier,
1277
1258
  completions: this.#editing ? this.#completions : [],
1278
1259
  onAutoComplete: this.#updateCompletions.bind(this),
1260
+ invokeGetter: this.onInvokeGetterClick.bind(this),
1261
+ startEditing: this.startEditing.bind(this),
1279
1262
  };
1280
- this.#view(input, {}, this.listItemElement);
1263
+ const that = this;
1264
+ const output: TreeElementViewOutput = {
1265
+ set nameElement(e: Element|undefined) {
1266
+ that.#nameElement = e;
1267
+ },
1268
+ set valueElement(e: Element|undefined) {
1269
+ that.#valueElement = e;
1270
+ },
1271
+ };
1272
+ this.#view(input, output, this.listItemElement);
1281
1273
  }
1282
1274
 
1283
1275
  getContextMenu(event: Event): UI.ContextMenu.ContextMenu {
@@ -1299,9 +1291,9 @@ export class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
1299
1291
  i18nString(UIStrings.copyValue), copyValueHandler, {jslogContext: 'copy-value'});
1300
1292
  }
1301
1293
  }
1302
- if (!this.property.property.synthetic && this.nameElement?.title) {
1294
+ if (!this.property.property.synthetic && this.property.path) {
1303
1295
  const copyPathHandler = Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText.bind(
1304
- Host.InspectorFrontendHost.InspectorFrontendHostInstance, this.nameElement.title);
1296
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance, this.property.path);
1305
1297
  contextMenu.clipboardSection().appendItem(
1306
1298
  i18nString(UIStrings.copyPropertyPath), copyPathHandler, {jslogContext: 'copy-property-path'});
1307
1299
  }
@@ -1375,7 +1367,7 @@ export class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
1375
1367
  void parent.onpopulate();
1376
1368
  }
1377
1369
  } else {
1378
- this.update();
1370
+ this.performUpdate();
1379
1371
  }
1380
1372
  return;
1381
1373
  }
@@ -1385,7 +1377,7 @@ export class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
1385
1377
  expression ? parentObject.setPropertyValue(property, expression) : parentObject.deleteProperty(property);
1386
1378
  const error = await errorPromise;
1387
1379
  if (error) {
1388
- this.update();
1380
+ this.performUpdate();
1389
1381
  return;
1390
1382
  }
1391
1383
 
@@ -1409,14 +1401,23 @@ export class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
1409
1401
  this.property.removeChildren();
1410
1402
  }
1411
1403
 
1412
- private onInvokeGetterClick(result: SDK.RemoteObject.CallFunctionResult): void {
1413
- if (!result.object) {
1404
+ async onInvokeGetterClick(getter: SDK.RemoteObject.RemoteObject): Promise<void> {
1405
+ const invokeGetter = `
1406
+ function invokeGetter(getter) {
1407
+ return Reflect.apply(getter, this, []);
1408
+ }`;
1409
+ // Also passing a string instead of a Function to avoid coverage implementation messing with it.
1410
+ const result = await this.property.parent
1411
+ ?.object
1412
+ // @ts-expect-error No way to teach TypeScript to preserve the Function-ness of `getter`.
1413
+ ?.callFunction(invokeGetter, [SDK.RemoteObject.RemoteObject.toCallArgument(getter)]);
1414
+ if (!result?.object) {
1414
1415
  return;
1415
1416
  }
1416
1417
  this.property.property.value = result.object;
1417
1418
  this.property.property.wasThrown = result.wasThrown || false;
1418
1419
 
1419
- this.update();
1420
+ this.performUpdate();
1420
1421
  this.invalidateChildren();
1421
1422
  this.updateExpandable();
1422
1423
  }
@@ -1432,7 +1433,7 @@ export class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
1432
1433
  }
1433
1434
 
1434
1435
  path(): string {
1435
- return this.nameElement.title;
1436
+ return this.property.path;
1436
1437
  }
1437
1438
  }
1438
1439