chrome-devtools-frontend 1.0.1571007 → 1.0.1572937

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 (168) hide show
  1. package/agents/prompts/README.md +18 -0
  2. package/agents/prompts/devtools-imports.md +47 -0
  3. package/agents/prompts/verification.md +27 -0
  4. package/front_end/Images/geminiInDevTools.png +0 -0
  5. package/front_end/Images/geminiInDevTools_2x.png +0 -0
  6. package/front_end/Images/src/database-off.svg +1 -0
  7. package/front_end/Images/src/lock-person.svg +1 -1
  8. package/front_end/core/common/Debouncer.ts +10 -1
  9. package/front_end/core/common/SettingRegistration.ts +1 -1
  10. package/front_end/core/host/AidaClient.ts +8 -0
  11. package/front_end/core/host/InspectorFrontendHostAPI.ts +0 -6
  12. package/front_end/core/host/UserMetrics.ts +1 -31
  13. package/front_end/core/root/ExperimentNames.ts +30 -0
  14. package/front_end/core/root/Runtime.ts +47 -48
  15. package/front_end/core/root/root.ts +2 -0
  16. package/front_end/core/sdk/CSSModel.ts +36 -13
  17. package/front_end/core/sdk/CSSProperty.ts +1 -1
  18. package/front_end/core/sdk/CSSPropertyParserMatchers.ts +9 -0
  19. package/front_end/core/sdk/CookieModel.ts +2 -1
  20. package/front_end/core/sdk/DOMModel.ts +1 -1
  21. package/front_end/core/sdk/DebuggerModel.ts +1 -1
  22. package/front_end/core/sdk/OverlayModel.ts +3 -2
  23. package/front_end/core/sdk/SourceMap.ts +1 -1
  24. package/front_end/devtools_compatibility.js +0 -6
  25. package/front_end/entrypoints/main/MainImpl.ts +44 -24
  26. package/front_end/entrypoints/main/main-meta.ts +1 -1
  27. package/front_end/generated/SupportedCSSProperties.js +6 -14
  28. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +0 -180
  29. package/front_end/models/ai_assistance/ai_assistance.ts +0 -2
  30. package/front_end/models/breakpoints/BreakpointManager.ts +3 -3
  31. package/front_end/models/issues_manager/ContrastCheckTrigger.ts +2 -2
  32. package/front_end/models/javascript_metadata/NativeFunctions.js +8 -0
  33. package/front_end/models/source_map_scopes/NamesResolver.ts +1 -1
  34. package/front_end/models/trace/EventsSerializer.ts +5 -1
  35. package/front_end/models/trace/ModelImpl.ts +0 -4
  36. package/front_end/models/trace/types/TraceEvents.ts +4 -0
  37. package/front_end/panels/accessibility/AXBreadcrumbsPane.ts +1 -1
  38. package/front_end/panels/accessibility/AccessibilitySidebarView.ts +1 -1
  39. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +8 -63
  40. package/front_end/panels/ai_assistance/PatchWidget.ts +10 -15
  41. package/front_end/panels/ai_assistance/SelectWorkspaceDialog.ts +5 -4
  42. package/front_end/panels/ai_assistance/aiAssistancePanel.css +0 -16
  43. package/front_end/panels/ai_assistance/ai_assistance.ts +0 -1
  44. package/front_end/panels/ai_assistance/components/ChatMessage.ts +3 -2
  45. package/front_end/panels/ai_assistance/components/ChatView.ts +123 -108
  46. package/front_end/panels/ai_assistance/components/PerformanceAgentMarkdownRenderer.ts +1 -145
  47. package/front_end/panels/application/DeviceBoundSessionsModel.ts +23 -1
  48. package/front_end/panels/application/DeviceBoundSessionsTreeElement.ts +23 -0
  49. package/front_end/panels/application/FrameDetailsView.ts +12 -10
  50. package/front_end/panels/application/components/BackForwardCacheView.ts +6 -8
  51. package/front_end/panels/application/components/BounceTrackingMitigationsView.ts +4 -3
  52. package/front_end/panels/application/components/ProtocolHandlersView.ts +5 -6
  53. package/front_end/panels/application/components/ReportsGrid.ts +9 -9
  54. package/front_end/panels/application/components/SharedStorageAccessGrid.ts +5 -4
  55. package/front_end/panels/application/components/TrustTokensView.ts +4 -6
  56. package/front_end/panels/application/preloading/PreloadingView.ts +9 -8
  57. package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +237 -230
  58. package/front_end/panels/application/preloading/components/PreloadingGrid.ts +3 -2
  59. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +6 -10
  60. package/front_end/panels/application/resourcesSidebar.css +8 -0
  61. package/front_end/panels/autofill/AutofillView.ts +4 -3
  62. package/front_end/panels/common/AiCodeCompletionSummaryToolbar.ts +3 -5
  63. package/front_end/panels/common/AiCodeCompletionTeaser.ts +5 -5
  64. package/front_end/panels/common/AiCodeGenerationTeaser.ts +35 -4
  65. package/front_end/panels/common/BadgeNotification.ts +17 -14
  66. package/front_end/panels/common/GdpSignUpDialog.ts +5 -6
  67. package/front_end/panels/common/GeminiRebrandPromoDialog.ts +192 -0
  68. package/front_end/panels/common/aiCodeGenerationTeaser.css +16 -1
  69. package/front_end/panels/common/common.ts +1 -0
  70. package/front_end/panels/common/geminiRebrandPromoDialog.css +47 -0
  71. package/front_end/panels/console/ConsoleInsightTeaser.ts +10 -11
  72. package/front_end/panels/console/ErrorStackParser.ts +11 -16
  73. package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +2 -2
  74. package/front_end/panels/css_overview/CSSOverviewModel.ts +1 -1
  75. package/front_end/panels/elements/ComputedStyleModel.ts +16 -65
  76. package/front_end/panels/elements/ComputedStyleWidget.ts +3 -3
  77. package/front_end/panels/elements/ElementsPanel.ts +35 -5
  78. package/front_end/panels/elements/ElementsSidebarPane.ts +1 -1
  79. package/front_end/panels/elements/ElementsTreeOutline.ts +1 -1
  80. package/front_end/panels/elements/PlatformFontsWidget.ts +1 -1
  81. package/front_end/panels/elements/StylePropertiesSection.ts +16 -8
  82. package/front_end/panels/elements/StylePropertyTreeElement.ts +67 -32
  83. package/front_end/panels/elements/StylesSidebarPane.ts +28 -11
  84. package/front_end/panels/elements/components/CSSHintDetailsView.ts +3 -2
  85. package/front_end/panels/elements/components/CSSPropertyDocsView.ts +3 -2
  86. package/front_end/panels/elements/elements-meta.ts +1 -1
  87. package/front_end/panels/emulation/DeviceModeWrapper.ts +101 -62
  88. package/front_end/panels/explain/components/ConsoleInsight.ts +27 -23
  89. package/front_end/panels/explain/components/consoleInsight.css +1 -1
  90. package/front_end/panels/issues/IssueView.ts +6 -6
  91. package/front_end/panels/network/RequestConditionsDrawer.ts +4 -3
  92. package/front_end/panels/network/RequestCookiesView.ts +3 -4
  93. package/front_end/panels/network/RequestTimingView.ts +6 -10
  94. package/front_end/panels/network/components/HeaderSectionRow.ts +3 -2
  95. package/front_end/panels/network/components/RequestHeaderSection.ts +3 -1
  96. package/front_end/panels/network/components/RequestHeadersView.css +2 -2
  97. package/front_end/panels/network/components/RequestHeadersView.ts +7 -6
  98. package/front_end/panels/profiler/HeapProfileView.ts +3 -3
  99. package/front_end/panels/profiler/HeapSnapshotView.ts +2 -2
  100. package/front_end/panels/profiler/profiler-meta.ts +3 -3
  101. package/front_end/panels/protocol_monitor/protocol_monitor-meta.ts +1 -1
  102. package/front_end/panels/recorder/RecorderController.ts +7 -13
  103. package/front_end/panels/recorder/components/CreateRecordingView.ts +6 -6
  104. package/front_end/panels/recorder/components/RecordingView.ts +0 -38
  105. package/front_end/panels/recorder/components/ReplaySection.ts +0 -14
  106. package/front_end/panels/recorder/components/StepEditor.ts +2 -40
  107. package/front_end/panels/recorder/recorderController.css +4 -4
  108. package/front_end/panels/security/CookieControlsView.ts +2 -2
  109. package/front_end/panels/security/CookieReportView.ts +21 -21
  110. package/front_end/panels/security/cookieControlsView.css +1 -1
  111. package/front_end/panels/security/cookieReportView.css +1 -1
  112. package/front_end/panels/settings/AISettingsTab.ts +13 -15
  113. package/front_end/panels/settings/components/SyncSection.ts +4 -3
  114. package/front_end/panels/settings/emulation/components/UserAgentClientHintsForm.ts +4 -12
  115. package/front_end/panels/settings/settings-meta.ts +1 -1
  116. package/front_end/panels/sources/BreakpointEditDialog.ts +4 -3
  117. package/front_end/panels/sources/CallStackSidebarPane.ts +4 -1
  118. package/front_end/panels/sources/FilteredUISourceCodeListProvider.ts +1 -1
  119. package/front_end/panels/sources/NavigatorView.ts +4 -4
  120. package/front_end/panels/sources/SourcesPanel.ts +7 -4
  121. package/front_end/panels/sources/components/HeadersView.ts +2 -2
  122. package/front_end/panels/timeline/CompatibilityTracksAppender.ts +3 -2
  123. package/front_end/panels/timeline/ThreadAppender.ts +2 -1
  124. package/front_end/panels/timeline/TimelineController.ts +4 -3
  125. package/front_end/panels/timeline/TimelinePanel.ts +7 -4
  126. package/front_end/panels/timeline/TimelineUIUtils.ts +2 -2
  127. package/front_end/panels/timeline/components/ExportTraceOptions.ts +4 -4
  128. package/front_end/panels/timeline/components/FieldSettingsDialog.ts +13 -6
  129. package/front_end/panels/timeline/components/LiveMetricsView.ts +13 -9
  130. package/front_end/panels/timeline/components/exportTraceOptions.css +1 -1
  131. package/front_end/panels/timeline/components/fieldSettingsDialog.css +1 -1
  132. package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +2 -19
  133. package/front_end/panels/timeline/components/insights/InsightRenderer.ts +3 -4
  134. package/front_end/panels/timeline/components/insights/baseInsightComponent.css +0 -5
  135. package/front_end/panels/timeline/components/liveMetricsView.css +1 -1
  136. package/front_end/panels/whats_new/ReleaseNoteView.ts +4 -3
  137. package/front_end/third_party/chromium/README.chromium +1 -1
  138. package/front_end/ui/components/buttons/button.css +4 -0
  139. package/front_end/ui/components/markdown_view/CodeBlock.ts +3 -6
  140. package/front_end/ui/components/markdown_view/MarkdownLink.ts +3 -4
  141. package/front_end/ui/components/panel_feedback/PanelFeedback.ts +3 -4
  142. package/front_end/ui/components/panel_feedback/PreviewToggle.ts +10 -7
  143. package/front_end/ui/components/panel_feedback/panelFeedback.css +2 -2
  144. package/front_end/ui/components/panel_feedback/previewToggle.css +2 -2
  145. package/front_end/ui/components/text_editor/AiCodeGenerationParser.ts +27 -8
  146. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +36 -6
  147. package/front_end/ui/kit/link/Link.ts +1 -14
  148. package/front_end/ui/legacy/ActionRegistration.ts +1 -1
  149. package/front_end/ui/legacy/ContextMenu.ts +2 -2
  150. package/front_end/ui/legacy/EmptyWidget.ts +3 -3
  151. package/front_end/ui/legacy/LinkContextMenuProvider.ts +42 -0
  152. package/front_end/ui/legacy/ViewRegistration.ts +1 -1
  153. package/front_end/ui/legacy/XLink.ts +0 -27
  154. package/front_end/ui/legacy/components/color_picker/ContrastDetails.ts +1 -1
  155. package/front_end/ui/legacy/components/color_picker/ContrastOverlay.ts +5 -4
  156. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +2 -2
  157. package/front_end/ui/legacy/components/perf_ui/perf_ui-meta.ts +1 -1
  158. package/front_end/ui/legacy/inspectorCommon.css +2 -1
  159. package/front_end/ui/legacy/legacy.ts +3 -1
  160. package/front_end/ui/visual_logging/KnownContextValues.ts +4 -1
  161. package/front_end/ui/visual_logging/LoggingDriver.ts +3 -0
  162. package/package.json +1 -1
  163. package/front_end/models/ai_assistance/ArtifactsManager.ts +0 -67
  164. package/front_end/panels/ai_assistance/components/ArtifactsViewer.ts +0 -183
  165. package/front_end/panels/ai_assistance/components/CollapsibleAssistanceContentWidget.ts +0 -89
  166. package/front_end/panels/ai_assistance/components/PerformanceAgentFlameChart.ts +0 -133
  167. package/front_end/panels/ai_assistance/components/artifactsViewer.css +0 -15
  168. package/front_end/panels/ai_assistance/components/collapsibleAssistanceContentWidget.css +0 -32
@@ -10,6 +10,7 @@ import * as i18n from '../../core/i18n/i18n.js';
10
10
  import * as Platform from '../../core/platform/platform.js';
11
11
  import * as Root from '../../core/root/root.js';
12
12
  import * as SDK from '../../core/sdk/sdk.js';
13
+ import type * as Protocol from '../../generated/protocol.js';
13
14
  import * as Badges from '../../models/badges/badges.js';
14
15
  import * as Bindings from '../../models/bindings/bindings.js';
15
16
  import * as TextUtils from '../../models/text_utils/text_utils.js';
@@ -170,7 +171,8 @@ export class EnvFunctionRenderer extends rendererBase(SDK.CSSPropertyParserMatch
170
171
  // clang-format on
171
172
  constructor(
172
173
  readonly treeElement: StylePropertyTreeElement|null,
173
- readonly matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, readonly computedStyles: Map<string, string>) {
174
+ readonly matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, readonly computedStyles: Map<string, string>,
175
+ readonly computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null) {
174
176
  super();
175
177
  }
176
178
  override render(match: SDK.CSSPropertyParserMatchers.EnvFunctionMatch, context: RenderingContext): Node[] {
@@ -187,7 +189,8 @@ export class EnvFunctionRenderer extends rendererBase(SDK.CSSPropertyParserMatch
187
189
 
188
190
  const span = document.createElement('span');
189
191
  const func =
190
- this.treeElement?.getTracingTooltip('env', match.node, this.matchedStyles, this.computedStyles, context) ??
192
+ this.treeElement?.getTracingTooltip(
193
+ 'env', match.node, this.matchedStyles, this.computedStyles, this.computedStyleExtraFields, context) ??
191
194
  'env';
192
195
  const valueClass = classMap({'inactive-value': !match.varNameIsValid});
193
196
  const fallbackClass = classMap({'inactive-value': match.varNameIsValid});
@@ -315,14 +318,17 @@ export class VariableRenderer extends rendererBase(SDK.CSSPropertyParserMatchers
315
318
  readonly #treeElement: StylePropertyTreeElement|null;
316
319
  readonly #matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles;
317
320
  readonly #computedStyles: Map<string, string>;
321
+ readonly #computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null;
318
322
  constructor(
319
323
  stylesPane: StylesSidebarPane, treeElement: StylePropertyTreeElement|null,
320
- matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, computedStyles: Map<string, string>) {
324
+ matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, computedStyles: Map<string, string>,
325
+ computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null) {
321
326
  super();
322
327
  this.#treeElement = treeElement;
323
328
  this.#stylesPane = stylesPane;
324
329
  this.#matchedStyles = matchedStyles;
325
330
  this.#computedStyles = computedStyles;
331
+ this.#computedStyleExtraFields = computedStyleExtraFields;
326
332
  }
327
333
 
328
334
  override render(match: SDK.CSSPropertyParserMatchers.VariableMatch, context: RenderingContext): Node[] {
@@ -343,7 +349,8 @@ export class VariableRenderer extends rendererBase(SDK.CSSPropertyParserMatchers
343
349
  {name: declaration.name, value: declaration.value ?? ''},
344
350
  substitution.cachedParsedValue(declaration.declaration, this.#matchedStyles, this.#computedStyles),
345
351
  getPropertyRenderers(
346
- declaration.name, declaration.style, this.#stylesPane, this.#matchedStyles, null, this.#computedStyles),
352
+ declaration.name, declaration.style, this.#stylesPane, this.#matchedStyles, null, this.#computedStyles,
353
+ this.#computedStyleExtraFields),
347
354
  substitution);
348
355
  cssControls.forEach((value, key) => value.forEach(control => context.addControl(key, control)));
349
356
  return nodes;
@@ -355,8 +362,8 @@ export class VariableRenderer extends rendererBase(SDK.CSSPropertyParserMatchers
355
362
 
356
363
  const renderedFallback = match.fallback ? Renderer.render(match.fallback, context) : undefined;
357
364
 
358
- const varCall =
359
- this.#treeElement?.getTracingTooltip('var', match.node, this.#matchedStyles, this.#computedStyles, context);
365
+ const varCall = this.#treeElement?.getTracingTooltip(
366
+ 'var', match.node, this.#matchedStyles, this.#computedStyles, this.#computedStyleExtraFields, context);
360
367
  const tooltipContents =
361
368
  this.#stylesPane.getVariablePopoverContents(this.#matchedStyles, match.name, variableValue ?? null);
362
369
  const tooltipId = this.#treeElement?.getTooltipId('custom-property-var');
@@ -427,14 +434,17 @@ export class AttributeRenderer extends rendererBase(SDK.CSSPropertyParserMatcher
427
434
  readonly #treeElement: StylePropertyTreeElement|null;
428
435
  readonly #matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles;
429
436
  readonly #computedStyles: Map<string, string>;
437
+ readonly #computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null;
430
438
  constructor(
431
439
  stylesPane: StylesSidebarPane, treeElement: StylePropertyTreeElement|null,
432
- matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, computedStyles: Map<string, string>) {
440
+ matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, computedStyles: Map<string, string>,
441
+ computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null) {
433
442
  super();
434
443
  this.#treeElement = treeElement;
435
444
  this.#stylesPane = stylesPane;
436
445
  this.#matchedStyles = matchedStyles;
437
446
  this.#computedStyles = computedStyles;
447
+ this.#computedStyleExtraFields = computedStyleExtraFields;
438
448
  }
439
449
 
440
450
  override render(match: SDK.CSSPropertyParserMatchers.AttributeMatch, context: RenderingContext): Node[] {
@@ -473,7 +483,8 @@ export class AttributeRenderer extends rendererBase(SDK.CSSPropertyParserMatcher
473
483
  .renderValueNodes(
474
484
  {name: '--property', value: match.substitutionText}, matching,
475
485
  getPropertyRenderers(
476
- '--property', match.style, this.#stylesPane, this.#matchedStyles, null, this.#computedStyles),
486
+ '--property', match.style, this.#stylesPane, this.#matchedStyles, null, this.#computedStyles,
487
+ this.#computedStyleExtraFields),
477
488
  substitution)
478
489
  .nodes;
479
490
  }
@@ -481,8 +492,8 @@ export class AttributeRenderer extends rendererBase(SDK.CSSPropertyParserMatcher
481
492
 
482
493
  const renderedFallback = match.fallback ? Renderer.render(match.fallback, context) : undefined;
483
494
 
484
- const attrCall =
485
- this.#treeElement?.getTracingTooltip('attr', match.node, this.#matchedStyles, this.#computedStyles, context);
495
+ const attrCall = this.#treeElement?.getTracingTooltip(
496
+ 'attr', match.node, this.#matchedStyles, this.#computedStyles, this.#computedStyleExtraFields, context);
486
497
  const tooltipId = attributeMissing ? undefined : this.#treeElement?.getTooltipId('custom-attribute');
487
498
  const tooltip = tooltipId ? {tooltipId} : undefined;
488
499
  // clang-format off
@@ -636,7 +647,7 @@ export class ColorRenderer extends rendererBase(SDK.CSSPropertyParserMatchers.Co
636
647
  html`${
637
648
  this.#treeElement?.getTracingTooltip(
638
649
  func, match.node, this.#treeElement.matchedStyles(), this.#treeElement.getComputedStyles() ?? new Map(),
639
- renderingContext) ??
650
+ this.#treeElement.getComputedStyleExtraFields(), renderingContext) ??
640
651
  func}${nodes}`,
641
652
  valueChild);
642
653
 
@@ -871,15 +882,18 @@ export class ColorMixRenderer extends rendererBase(SDK.CSSPropertyParserMatchers
871
882
  readonly #pane: StylesSidebarPane;
872
883
  readonly #matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles;
873
884
  readonly #computedStyles: Map<string, string>;
885
+ readonly #computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null;
874
886
  readonly #treeElement: StylePropertyTreeElement|null;
875
887
 
876
888
  constructor(
877
889
  pane: StylesSidebarPane, matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles,
878
- computedStyles: Map<string, string>, treeElement: StylePropertyTreeElement|null) {
890
+ computedStyles: Map<string, string>, computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null,
891
+ treeElement: StylePropertyTreeElement|null) {
879
892
  super();
880
893
  this.#pane = pane;
881
894
  this.#matchedStyles = matchedStyles;
882
895
  this.#computedStyles = computedStyles;
896
+ this.#computedStyleExtraFields = computedStyleExtraFields;
883
897
  this.#treeElement = treeElement;
884
898
  }
885
899
 
@@ -915,7 +929,8 @@ export class ColorMixRenderer extends rendererBase(SDK.CSSPropertyParserMatchers
915
929
  render(
916
930
  html`${
917
931
  this.#treeElement?.getTracingTooltip(
918
- 'color-mix', match.node, this.#matchedStyles, this.#computedStyles, context) ??
932
+ 'color-mix', match.node, this.#matchedStyles, this.#computedStyles, this.#computedStyleExtraFields,
933
+ context) ??
919
934
  'color-mix'}(${Renderer.render(match.space, childRenderingContexts[0]).nodes}, ${color1.nodes}, ${
920
935
  color2.nodes})`,
921
936
  contentChild);
@@ -1190,12 +1205,13 @@ export class BezierRenderer extends rendererBase(SDK.CSSPropertyParserMatchers.B
1190
1205
 
1191
1206
  // clang-format off
1192
1207
  export class AutoBaseRenderer extends rendererBase(SDK.CSSPropertyParserMatchers.AutoBaseMatch) {
1193
- readonly #computedStyle: Map<string, string>;
1208
+ readonly #computedStyleExtraFields : Protocol.CSS.ComputedStyleExtraFields|null;
1194
1209
  // clang-format on
1195
1210
 
1196
- constructor(computedStyle: Map<string, string>) {
1211
+ constructor(
1212
+ computedStyle: Map<string, string>, computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null) {
1197
1213
  super();
1198
- this.#computedStyle = computedStyle;
1214
+ this.#computedStyleExtraFields = computedStyleExtraFields;
1199
1215
  }
1200
1216
 
1201
1217
  override render(match: SDK.CSSPropertyParserMatchers.AutoBaseMatch, context: RenderingContext): Node[] {
@@ -1209,8 +1225,9 @@ export class AutoBaseRenderer extends rendererBase(SDK.CSSPropertyParserMatchers
1209
1225
  Renderer.renderInto(match.auto, context, auto);
1210
1226
  Renderer.renderInto(match.base, context, base);
1211
1227
 
1212
- const activeAppearance = this.#computedStyle.get('appearance');
1213
- if (activeAppearance?.startsWith('base')) {
1228
+ // TODO(crbug.com/475522248): Consider cases with nested elements which
1229
+ // support base appearance and ensure the logic matches StyleAdjuster in blink.
1230
+ if (this.#computedStyleExtraFields?.isAppearanceBase) {
1214
1231
  auto.classList.add('inactive-value');
1215
1232
  } else {
1216
1233
  base.classList.add('inactive-value');
@@ -1668,14 +1685,17 @@ export class BaseFunctionRenderer extends rendererBase(SDK.CSSPropertyParserMatc
1668
1685
  readonly #stylesPane: StylesSidebarPane;
1669
1686
  readonly #matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles;
1670
1687
  readonly #computedStyles: Map<string, string>;
1688
+ readonly #computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null;
1671
1689
  readonly #treeElement: StylePropertyTreeElement|null;
1672
1690
  readonly #propertyName: string;
1673
1691
  constructor(
1674
1692
  stylesPane: StylesSidebarPane, matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles,
1675
- computedStyles: Map<string, string>, propertyName: string, treeElement: StylePropertyTreeElement|null) {
1693
+ computedStyles: Map<string, string>, computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null,
1694
+ propertyName: string, treeElement: StylePropertyTreeElement|null) {
1676
1695
  super();
1677
1696
  this.#matchedStyles = matchedStyles;
1678
1697
  this.#computedStyles = computedStyles;
1698
+ this.#computedStyleExtraFields = computedStyleExtraFields;
1679
1699
  this.#stylesPane = stylesPane;
1680
1700
  this.#treeElement = treeElement;
1681
1701
  this.#propertyName = propertyName;
@@ -1694,7 +1714,8 @@ export class BaseFunctionRenderer extends rendererBase(SDK.CSSPropertyParserMatc
1694
1714
  render(
1695
1715
  html`${
1696
1716
  this.#treeElement?.getTracingTooltip(
1697
- match.func, match.node, this.#matchedStyles, this.#computedStyles, context) ??
1717
+ match.func, match.node, this.#matchedStyles, this.#computedStyles, this.#computedStyleExtraFields,
1718
+ context) ??
1698
1719
  match.func}(${renderedArgs.map((arg, idx) => idx === 0 ? [arg] : [html`, `, arg]).flat()})`,
1699
1720
  span);
1700
1721
 
@@ -1911,11 +1932,12 @@ export class PositionTryRenderer extends rendererBase(SDK.CSSPropertyParserMatch
1911
1932
  export function getPropertyRenderers(
1912
1933
  propertyName: string, style: SDK.CSSStyleDeclaration.CSSStyleDeclaration, stylesPane: StylesSidebarPane,
1913
1934
  matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, treeElement: StylePropertyTreeElement|null,
1914
- computedStyles: Map<string, string>): Array<MatchRenderer<SDK.CSSPropertyParser.Match>> {
1935
+ computedStyles: Map<string, string>, computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null):
1936
+ Array<MatchRenderer<SDK.CSSPropertyParser.Match>> {
1915
1937
  return [
1916
- new VariableRenderer(stylesPane, treeElement, matchedStyles, computedStyles),
1938
+ new VariableRenderer(stylesPane, treeElement, matchedStyles, computedStyles, computedStyleExtraFields),
1917
1939
  new ColorRenderer(stylesPane, treeElement),
1918
- new ColorMixRenderer(stylesPane, matchedStyles, computedStyles, treeElement),
1940
+ new ColorMixRenderer(stylesPane, matchedStyles, computedStyles, computedStyleExtraFields, treeElement),
1919
1941
  new URLRenderer(style.parentRule, stylesPane.node()),
1920
1942
  new AngleRenderer(treeElement),
1921
1943
  new LinkableNameRenderer(matchedStyles, stylesPane),
@@ -1929,15 +1951,17 @@ export function getPropertyRenderers(
1929
1951
  new AnchorFunctionRenderer(stylesPane),
1930
1952
  new PositionAnchorRenderer(stylesPane),
1931
1953
  new FlexGridRenderer(stylesPane, treeElement),
1932
- new EnvFunctionRenderer(treeElement, matchedStyles, computedStyles),
1954
+ new EnvFunctionRenderer(treeElement, matchedStyles, computedStyles, computedStyleExtraFields),
1933
1955
  new PositionTryRenderer(matchedStyles),
1934
1956
  new LengthRenderer(stylesPane, propertyName, treeElement),
1935
- new MathFunctionRenderer(stylesPane, matchedStyles, computedStyles, propertyName, treeElement),
1936
- new CustomFunctionRenderer(stylesPane, matchedStyles, computedStyles, propertyName, treeElement),
1937
- new AutoBaseRenderer(computedStyles),
1957
+ new MathFunctionRenderer(
1958
+ stylesPane, matchedStyles, computedStyles, computedStyleExtraFields, propertyName, treeElement),
1959
+ new CustomFunctionRenderer(
1960
+ stylesPane, matchedStyles, computedStyles, computedStyleExtraFields, propertyName, treeElement),
1961
+ new AutoBaseRenderer(computedStyles, computedStyleExtraFields),
1938
1962
  new BinOpRenderer(),
1939
1963
  new RelativeColorChannelRenderer(treeElement),
1940
- new AttributeRenderer(stylesPane, treeElement, matchedStyles, computedStyles),
1964
+ new AttributeRenderer(stylesPane, treeElement, matchedStyles, computedStyles, computedStyleExtraFields),
1941
1965
  ];
1942
1966
  }
1943
1967
 
@@ -1962,6 +1986,7 @@ export class StylePropertyTreeElement extends UI.TreeOutline.TreeElement {
1962
1986
  private lastComputedValue: string|null = null;
1963
1987
  private computedStyles: Map<string, string>|null = null;
1964
1988
  private parentsComputedStyles: Map<string, string>|null = null;
1989
+ private computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null = null;
1965
1990
  private contextForTest!: Context|undefined;
1966
1991
  #gridNames: Set<string>|undefined = undefined;
1967
1992
  #tooltipKeyCounts = new Map<string, number>();
@@ -2070,6 +2095,14 @@ export class StylePropertyTreeElement extends UI.TreeOutline.TreeElement {
2070
2095
  return this.computedStyles;
2071
2096
  }
2072
2097
 
2098
+ setComputedStyleExtraFields(computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null): void {
2099
+ this.computedStyleExtraFields = computedStyleExtraFields;
2100
+ }
2101
+
2102
+ getComputedStyleExtraFields(): Protocol.CSS.ComputedStyleExtraFields|null {
2103
+ return this.computedStyleExtraFields;
2104
+ }
2105
+
2073
2106
  setParentsComputedStyles(parentsComputedStyles: Map<string, string>|null): void {
2074
2107
  this.parentsComputedStyles = parentsComputedStyles;
2075
2108
  }
@@ -2345,10 +2378,11 @@ export class StylePropertyTreeElement extends UI.TreeOutline.TreeElement {
2345
2378
 
2346
2379
  const renderers = this.property.parsedOk ?
2347
2380
  getPropertyRenderers(
2348
- this.name, this.style, this.#parentPane, this.#matchedStyles, this, this.getComputedStyles() ?? new Map()) :
2381
+ this.name, this.style, this.#parentPane, this.#matchedStyles, this, this.getComputedStyles() ?? new Map(),
2382
+ this.getComputedStyleExtraFields()) :
2349
2383
  [];
2350
2384
 
2351
- if (Root.Runtime.experiments.isEnabled('font-editor') && this.property.parsedOk) {
2385
+ if (Root.Runtime.experiments.isEnabled(Root.ExperimentNames.ExperimentName.FONT_EDITOR) && this.property.parsedOk) {
2352
2386
  renderers.push(new FontRenderer(this));
2353
2387
  }
2354
2388
  this.listItemElement.removeChildren();
@@ -2544,7 +2578,8 @@ export class StylePropertyTreeElement extends UI.TreeOutline.TreeElement {
2544
2578
 
2545
2579
  getTracingTooltip(
2546
2580
  functionName: string, node: CodeMirror.SyntaxNode, matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles,
2547
- computedStyles: Map<string, string>, context: RenderingContext): Lit.TemplateResult {
2581
+ computedStyles: Map<string, string>, computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null,
2582
+ context: RenderingContext): Lit.TemplateResult {
2548
2583
  if (context.tracing || !context.property) {
2549
2584
  return html`${functionName}`;
2550
2585
  }
@@ -2569,7 +2604,7 @@ export class StylePropertyTreeElement extends UI.TreeOutline.TreeElement {
2569
2604
  ?.showTrace(
2570
2605
  property, text, matchedStyles, computedStyles,
2571
2606
  getPropertyRenderers(property.name,
2572
- property.ownerStyle, stylesPane, matchedStyles, null, computedStyles),
2607
+ property.ownerStyle, stylesPane, matchedStyles, null, computedStyles, computedStyleExtraFields),
2573
2608
  expandPercentagesInShorthands, shorthandPositionOffset, this.openedViaHotkey);
2574
2609
  }
2575
2610
  }}
@@ -576,14 +576,17 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
576
576
  const nodeId = this.node()?.id;
577
577
  const parentNodeId = this.matchedStyles?.getParentLayoutNodeId();
578
578
 
579
- const [computedStyles, parentsComputedStyles] =
580
- await Promise.all([this.fetchComputedStylesFor(nodeId), this.fetchComputedStylesFor(parentNodeId)]);
579
+ const [computedStyles, parentsComputedStyles, computedStyleExtraFields] = await Promise.all([
580
+ this.fetchComputedStylesFor(nodeId), this.fetchComputedStylesFor(parentNodeId),
581
+ this.fetchComputedStyleExtraFieldsFor(nodeId)
582
+ ]);
581
583
 
582
584
  if (signal.aborted) {
583
585
  return;
584
586
  }
585
587
 
586
- await this.innerRebuildUpdate(signal, this.matchedStyles, computedStyles, parentsComputedStyles);
588
+ await this.innerRebuildUpdate(
589
+ signal, this.matchedStyles, computedStyles, parentsComputedStyles, computedStyleExtraFields);
587
590
 
588
591
  if (signal.aborted) {
589
592
  return;
@@ -633,6 +636,15 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
633
636
  return await node.domModel().cssModel().getComputedStyle(nodeId);
634
637
  }
635
638
 
639
+ private async fetchComputedStyleExtraFieldsFor(nodeId: Protocol.DOM.NodeId|undefined):
640
+ Promise<Protocol.CSS.ComputedStyleExtraFields|null> {
641
+ const node = this.node();
642
+ if (node === null || nodeId === undefined) {
643
+ return null;
644
+ }
645
+ return await node.domModel().cssModel().getComputedStyleExtraFields(nodeId);
646
+ }
647
+
636
648
  override onResize(): void {
637
649
  void this.resizeThrottler.schedule(this.#resize.bind(this));
638
650
  }
@@ -914,7 +926,8 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
914
926
 
915
927
  private async innerRebuildUpdate(
916
928
  signal: AbortSignal, matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles|null,
917
- computedStyles: Map<string, string>|null, parentsComputedStyles: Map<string, string>|null): Promise<void> {
929
+ computedStyles: Map<string, string>|null, parentsComputedStyles: Map<string, string>|null,
930
+ computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null): Promise<void> {
918
931
  // ElementsSidebarPane's throttler schedules this method. Usually,
919
932
  // rebuild is suppressed while editing (see onCSSModelChanged()), but we need a
920
933
  // 'force' flag since the currently running throttler process cannot be canceled.
@@ -940,7 +953,8 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
940
953
  }
941
954
 
942
955
  const blocks = await this.rebuildSectionsForMatchedStyleRules(
943
- (matchedStyles as SDK.CSSMatchedStyles.CSSMatchedStyles), computedStyles, parentsComputedStyles);
956
+ (matchedStyles as SDK.CSSMatchedStyles.CSSMatchedStyles), computedStyles, parentsComputedStyles,
957
+ computedStyleExtraFields);
944
958
 
945
959
  if (signal.aborted) {
946
960
  return;
@@ -1023,13 +1037,16 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1023
1037
 
1024
1038
  rebuildSectionsForMatchedStyleRulesForTest(
1025
1039
  matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, computedStyles: Map<string, string>|null,
1026
- parentsComputedStyles: Map<string, string>|null): Promise<SectionBlock[]> {
1027
- return this.rebuildSectionsForMatchedStyleRules(matchedStyles, computedStyles, parentsComputedStyles);
1040
+ parentsComputedStyles: Map<string, string>|null,
1041
+ computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null): Promise<SectionBlock[]> {
1042
+ return this.rebuildSectionsForMatchedStyleRules(
1043
+ matchedStyles, computedStyles, parentsComputedStyles, computedStyleExtraFields);
1028
1044
  }
1029
1045
 
1030
1046
  private async rebuildSectionsForMatchedStyleRules(
1031
1047
  matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, computedStyles: Map<string, string>|null,
1032
- parentsComputedStyles: Map<string, string>|null): Promise<SectionBlock[]> {
1048
+ parentsComputedStyles: Map<string, string>|null,
1049
+ computedStyleExtraFields: Protocol.CSS.ComputedStyleExtraFields|null): Promise<SectionBlock[]> {
1033
1050
  if (this.idleCallbackManager) {
1034
1051
  this.idleCallbackManager.discard();
1035
1052
  }
@@ -1077,8 +1094,8 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1077
1094
  style.type === SDK.CSSStyleDeclaration.Type.Animation;
1078
1095
  if (lastBlock && (!isTransitionOrAnimationStyle || style.allProperties().length > 0)) {
1079
1096
  this.idleCallbackManager.schedule(() => {
1080
- const section =
1081
- new StylePropertiesSection(this, matchedStyles, style, sectionIdx, computedStyles, parentsComputedStyles);
1097
+ const section = new StylePropertiesSection(
1098
+ this, matchedStyles, style, sectionIdx, computedStyles, parentsComputedStyles, computedStyleExtraFields);
1082
1099
  sectionIdx++;
1083
1100
  lastBlock.sections.push(section);
1084
1101
  });
@@ -1151,7 +1168,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1151
1168
  const lastBlock = blocks[blocks.length - 1];
1152
1169
  this.idleCallbackManager.schedule(() => {
1153
1170
  const section = new HighlightPseudoStylePropertiesSection(
1154
- this, matchedStyles, style, sectionIdx, computedStyles, parentsComputedStyles);
1171
+ this, matchedStyles, style, sectionIdx, computedStyles, parentsComputedStyles, computedStyleExtraFields);
1155
1172
  sectionIdx++;
1156
1173
  lastBlock.sections.push(section);
1157
1174
  });
@@ -3,6 +3,7 @@
3
3
  // found in the LICENSE file.
4
4
  /* eslint-disable @devtools/no-lit-render-outside-of-view */
5
5
 
6
+ import '../../../ui/kit/kit.js';
6
7
  import '../../../ui/legacy/legacy.js';
7
8
 
8
9
  import * as i18n from '../../../core/i18n/i18n.js';
@@ -51,9 +52,9 @@ export class CSSHintDetailsView extends HTMLElement {
51
52
  ` : ''}
52
53
  ${link ? html`
53
54
  <div class="footer">
54
- <x-link id="learn-more" href=${link} class="clickable underlined unbreakable-text">
55
+ <devtools-link id="learn-more" href=${link} class="clickable underlined unbreakable-text">
55
56
  ${i18nString(UIStrings.learnMore)}
56
- </x-link>
57
+ </devtools-link>
57
58
  </div>
58
59
  `: ''}
59
60
  </div>
@@ -3,6 +3,7 @@
3
3
  // found in the LICENSE file.
4
4
  /* eslint-disable @devtools/no-lit-render-outside-of-view */
5
5
 
6
+ import '../../../ui/kit/kit.js';
6
7
  import '../../../ui/legacy/legacy.js';
7
8
 
8
9
  import * as Common from '../../../core/common/common.js';
@@ -250,13 +251,13 @@ export class CSSPropertyDocsView extends HTMLElement {
250
251
  ` : nothing}
251
252
  ${link ? html`
252
253
  <div class="docs-popup-section footer">
253
- <x-link
254
+ <devtools-link
254
255
  id="learn-more"
255
256
  href=${link}
256
257
  class="clickable underlined unbreakable-text"
257
258
  >
258
259
  ${i18nString(UIStrings.learnMore)}
259
- </x-link>
260
+ </devtools-link>
260
261
  <devtools-checkbox
261
262
  @change=${this.#dontShowChanged}
262
263
  jslog=${VisualLogging.toggle('css-property-doc').track({ change: true })}>
@@ -238,7 +238,7 @@ UI.ViewManager.registerViewExtension({
238
238
  });
239
239
 
240
240
  UI.ViewManager.registerViewExtension({
241
- experiment: Root.Runtime.ExperimentName.CAPTURE_NODE_CREATION_STACKS,
241
+ experiment: Root.ExperimentNames.ExperimentName.CAPTURE_NODE_CREATION_STACKS,
242
242
  location: UI.ViewManager.ViewLocationValues.ELEMENTS_SIDEBAR,
243
243
  id: 'elements.dom-creation',
244
244
  commandPrompt: i18nLazyString(UIStrings.showStackTrace),
@@ -123,73 +123,47 @@ export class ActionDelegate implements UI.ActionRegistration.ActionDelegate {
123
123
  return;
124
124
  }
125
125
 
126
+ // Resolve to a remote object to ensure the node is alive in the context.
126
127
  const object = await node.resolveToObject();
127
128
  if (!object) {
128
129
  return;
129
130
  }
130
- const result = await object.callFunction(function(this: Element) {
131
- function getFrameOffset(frame: Element|null): {x: number, y: number} {
132
- if (!frame) {
133
- return {x: 0, y: 0};
134
- }
135
-
136
- // The offset of the frame's content relative to the frame element
137
- // contains the border width and the padding.
138
- // The border width.
139
- const borderTop = frame.clientTop;
140
- const borderLeft = frame.clientLeft;
141
-
142
- // The padding can be retrieved via computed styles.
143
- const styles = window.getComputedStyle(frame);
144
- const paddingTop = parseFloat(styles.paddingTop);
145
- const paddingLeft = parseFloat(styles.paddingLeft);
146
-
147
- // The position of the frame in it's parent.
148
- const rect = frame.getBoundingClientRect();
149
-
150
- // The offset of the parent frame's content relative to the
151
- // document. If there is no parent frame, the offset is 0.
152
- // In case of OOPiF, there is no access to the parent frame's
153
- // offset.
154
- const parentFrameOffset = getFrameOffset(frame.ownerDocument.defaultView?.frameElement ?? null);
155
-
156
- // The scroll position of the frame.
157
- const scrollX = frame.ownerDocument.defaultView?.scrollX ?? 0;
158
- const scrollY = frame.ownerDocument.defaultView?.scrollY ?? 0;
159
-
160
- return {
161
- x: parentFrameOffset.x + rect.left + borderLeft + paddingLeft + scrollX,
162
- y: parentFrameOffset.y + rect.top + borderTop + paddingTop + scrollY,
163
- };
164
- }
165
-
166
- // The bounding client rect of the node relative to the viewport.
167
- const rect = this.getBoundingClientRect();
168
- const frameOffset = getFrameOffset(this.ownerDocument.defaultView?.frameElement ?? null);
169
-
170
- // The scroll position of the frame.
171
- const scrollX = this.ownerDocument.defaultView?.scrollX ?? 0;
172
- const scrollY = this.ownerDocument.defaultView?.scrollY ?? 0;
173
-
174
- // The offset of the node's content relative to the top-level
175
- // document is the sum of the element offset relative to the
176
- // document's viewport, the document's scroll position, and the
177
- // parent's offset relative to the top-level document.
178
- return JSON.stringify({
179
- x: rect.left + frameOffset.x + scrollX,
180
- y: rect.top + frameOffset.y + scrollY,
181
- width: rect.width,
182
- height: rect.height,
183
- scale: 1,
184
- });
185
- });
186
- if (!result.object) {
187
- throw new Error('Clipping error: could not get object data.');
131
+
132
+ // Get the Box Model via CDP.
133
+ // This returns the quads relative to the target's viewport.
134
+ // We use the 'border' quad to include the border and padding in the screenshot,
135
+ // matching the 'width' and 'height' properties which are also Border Box dimensions.
136
+ const nodeBoxModel = await node.boxModel();
137
+ if (!nodeBoxModel) {
138
+ throw new Error(`Unable to get box model of the node: ${new Error().stack}`);
139
+ }
140
+ const nodeBorderQuad = nodeBoxModel.border;
141
+
142
+ // Get Layout Metrics to account for the Visual Viewport scroll and zoom.
143
+ const metrics = await node.domModel().target().pageAgent().invoke_getLayoutMetrics();
144
+ if (metrics.getError()) {
145
+ throw new Error(`Unable to get metrics: ${new Error().stack}`);
188
146
  }
189
- const clip = (JSON.parse((result.object.value as string)));
190
- const response = await node.domModel().target().pageAgent().invoke_getLayoutMetrics();
191
- const error = response.getError();
192
- const zoom = !error && response.visualViewport.zoom || 1;
147
+
148
+ const scrollX = metrics.cssVisualViewport.pageX;
149
+ const scrollY = metrics.cssVisualViewport.pageY;
150
+
151
+ // Calculate the global offset for OOPiFs (Out-of-Process iframes).
152
+ // This accounts for the position of the target's frame within the main page.
153
+ const {x: oopifOffsetX, y: oopifOffsetY} = await getOopifOffset(node.domModel().target());
154
+
155
+ // Assemble the final Clip.
156
+ // The absolute coordinates are: Global (OOPiF) + Viewport Scroll + Local Node Position (Border Box).
157
+ const clip = {
158
+ x: oopifOffsetX + scrollX + nodeBorderQuad[0],
159
+ y: oopifOffsetY + scrollY + nodeBorderQuad[1],
160
+ width: nodeBoxModel.width,
161
+ height: nodeBoxModel.height,
162
+ scale: 1,
163
+ };
164
+
165
+ // Apply Zoom factor.
166
+ const zoom = metrics.cssVisualViewport.zoom ?? 1;
193
167
  clip.x *= zoom;
194
168
  clip.y *= zoom;
195
169
  clip.width *= zoom;
@@ -210,3 +184,68 @@ export class ActionDelegate implements UI.ActionRegistration.ActionDelegate {
210
184
  return false;
211
185
  }
212
186
  }
187
+
188
+ /**
189
+ * Calculate the offset of the "Local Root" frame relative to the "Global Root" (the main frame).
190
+ * This involves traversing the CDP Targets for OOPiFs.
191
+ */
192
+ async function getOopifOffset(target: SDK.Target.Target|null): Promise<{x: number, y: number}> {
193
+ if (!target) {
194
+ return {x: 0, y: 0};
195
+ }
196
+
197
+ // Get the parent target. If there's no parent (we are at root) or it's not a frame, we are done.
198
+ const parentTarget = target.parentTarget();
199
+ if (!parentTarget || parentTarget.type() !== SDK.Target.Type.FRAME) {
200
+ return {x: 0, y: 0};
201
+ }
202
+
203
+ // Identify the current frame's ID to find its owner in the parent.
204
+ const frameId = target.model(SDK.ResourceTreeModel.ResourceTreeModel)?.mainFrame?.id;
205
+ if (!frameId) {
206
+ return {x: 0, y: 0};
207
+ }
208
+
209
+ // Get the DOMModel of the parent to query the frame owner element.
210
+ const parentDOMModel = parentTarget.model(SDK.DOMModel.DOMModel);
211
+ if (!parentDOMModel) {
212
+ return {x: 0, y: 0};
213
+ }
214
+
215
+ // Retrieve the frame owner node (e.g. the <iframe> element) in the parent's document.
216
+ const frameOwnerDeferred = await parentDOMModel.getOwnerNodeForFrame(frameId);
217
+ const frameOwner = await frameOwnerDeferred?.resolvePromise();
218
+ if (!frameOwner) {
219
+ return {x: 0, y: 0};
220
+ }
221
+
222
+ // Get the content box of the iframe element.
223
+ // This is relative to the parent target's viewport.
224
+ const boxModel = await frameOwner.boxModel();
225
+ if (!boxModel) {
226
+ return {x: 0, y: 0};
227
+ }
228
+
229
+ // content is a Quad [x1, y1, x2, y2, x3, y3, x4, y4]
230
+ const contentQuad = boxModel.content;
231
+ const iframeContentX = contentQuad[0];
232
+ const iframeContentY = contentQuad[1];
233
+
234
+ // Get the scroll position of the parent target to convert viewport-relative coordinates
235
+ // to document-relative coordinates.
236
+ const parentMetrics = await parentTarget.pageAgent().invoke_getLayoutMetrics();
237
+ if (parentMetrics.getError()) {
238
+ return {x: 0, y: 0};
239
+ }
240
+
241
+ const scrollX = parentMetrics.cssVisualViewport.pageX;
242
+ const scrollY = parentMetrics.cssVisualViewport.pageY;
243
+
244
+ // Recursively add the offset of the parent target itself (if it is also an OOPiF).
245
+ const parentOffset = await getOopifOffset(parentTarget);
246
+
247
+ return {
248
+ x: iframeContentX + scrollX + parentOffset.x,
249
+ y: iframeContentY + scrollY + parentOffset.y,
250
+ };
251
+ }