chrome-devtools-frontend 1.0.1556696 → 1.0.1559913

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 (201) hide show
  1. package/front_end/Images/src/container.svg +4 -0
  2. package/front_end/core/common/Gzip.ts +15 -0
  3. package/front_end/core/common/Object.ts +5 -1
  4. package/front_end/core/host/ResourceLoader.ts +1 -1
  5. package/front_end/core/host/UserMetrics.ts +3 -1
  6. package/front_end/core/sdk/CSSMetadata.ts +6 -6
  7. package/front_end/core/sdk/CSSModel.ts +2 -2
  8. package/front_end/core/sdk/DOMModel.ts +14 -3
  9. package/front_end/core/sdk/NetworkManager.ts +0 -7
  10. package/front_end/core/sdk/SourceMap.ts +16 -2
  11. package/front_end/core/sdk/SourceMapManager.ts +1 -1
  12. package/front_end/core/sdk/SourceMapScopesInfo.ts +11 -4
  13. package/front_end/entrypoints/formatter_worker/FormatterActions.ts +1 -0
  14. package/front_end/entrypoints/formatter_worker/ScopeParser.ts +51 -8
  15. package/front_end/entrypoints/main/GlobalAiButton.ts +5 -1
  16. package/front_end/generated/Deprecation.ts +0 -7
  17. package/front_end/generated/InspectorBackendCommands.ts +5 -4
  18. package/front_end/generated/SupportedCSSProperties.js +64 -32
  19. package/front_end/generated/protocol-mapping.d.ts +9 -0
  20. package/front_end/generated/protocol-proxy-api.d.ts +7 -0
  21. package/front_end/generated/protocol.ts +23 -1
  22. package/front_end/models/ai_assistance/agents/StylingAgent.ts +1 -1
  23. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +11 -7
  24. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +3 -3
  25. package/front_end/models/bindings/CompilerScriptMapping.ts +7 -6
  26. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +4 -4
  27. package/front_end/models/javascript_metadata/NativeFunctions.js +2 -2
  28. package/front_end/models/stack_trace/StackTraceImpl.ts +5 -3
  29. package/front_end/models/stack_trace/StackTraceModel.ts +53 -40
  30. package/front_end/models/trace/EventsSerializer.ts +8 -2
  31. package/front_end/models/trace/LanternComputationData.ts +4 -3
  32. package/front_end/models/trace/Processor.ts +6 -5
  33. package/front_end/models/trace/Styles.ts +10 -1
  34. package/front_end/models/trace/handlers/LargestImagePaintHandler.ts +2 -2
  35. package/front_end/models/trace/handlers/LayoutShiftsHandler.ts +2 -2
  36. package/front_end/models/trace/handlers/MetaHandler.ts +14 -0
  37. package/front_end/models/trace/handlers/PageLoadMetricsHandler.ts +54 -34
  38. package/front_end/models/trace/helpers/Timing.ts +8 -1
  39. package/front_end/models/trace/insights/Common.ts +1 -1
  40. package/front_end/models/trace/insights/LCPBreakdown.ts +4 -4
  41. package/front_end/models/trace/insights/LCPDiscovery.ts +3 -3
  42. package/front_end/models/trace/insights/RenderBlocking.ts +1 -1
  43. package/front_end/models/trace/insights/types.ts +1 -1
  44. package/front_end/models/trace/types/TraceEvents.ts +62 -10
  45. package/front_end/panels/application/AppManifestView.ts +134 -223
  46. package/front_end/panels/application/CookieItemsView.ts +1 -0
  47. package/front_end/panels/application/SharedStorageTreeElement.ts +3 -0
  48. package/front_end/panels/application/appManifestView.css +1 -1
  49. package/front_end/panels/common/AiCodeGenerationTeaser.ts +48 -12
  50. package/front_end/panels/common/aiCodeGenerationTeaser.css +14 -0
  51. package/front_end/panels/common/common.ts +1 -1
  52. package/front_end/panels/console/ConsoleViewMessage.ts +4 -3
  53. package/front_end/panels/console/consoleView.css +1 -1
  54. package/front_end/panels/elements/CSSRuleValidator.ts +38 -0
  55. package/front_end/panels/elements/ElementsTreeElement.ts +108 -58
  56. package/front_end/panels/elements/ElementsTreeOutline.ts +0 -17
  57. package/front_end/panels/elements/ElementsTreeOutlineRenderer.ts +7 -1
  58. package/front_end/panels/elements/StylesSidebarPane.ts +15 -4
  59. package/front_end/panels/elements/components/AdornerManager.ts +8 -0
  60. package/front_end/panels/emulation/DeviceModeToolbar.ts +3 -1
  61. package/front_end/panels/issues/AffectedResourcesView.ts +0 -1
  62. package/front_end/panels/lighthouse/LighthousePanel.ts +10 -0
  63. package/front_end/panels/lighthouse/lighthousePanel.css +46 -3
  64. package/front_end/panels/network/NetworkLogViewColumns.ts +9 -9
  65. package/front_end/panels/network/RequestCookiesView.ts +125 -141
  66. package/front_end/panels/network/components/RequestHeadersView.ts +2 -2
  67. package/front_end/panels/network/requestCookiesView.css +22 -20
  68. package/front_end/panels/recorder/components/RecordingView.ts +3 -3
  69. package/front_end/panels/recorder/components/StepView.ts +2 -1
  70. package/front_end/panels/settings/keybindsSettingsTab.css +4 -0
  71. package/front_end/panels/sources/CallStackSidebarPane.ts +7 -3
  72. package/front_end/panels/sources/DebuggerPausedMessage.ts +125 -90
  73. package/front_end/panels/sources/SourcesPanel.ts +10 -7
  74. package/front_end/panels/sources/debuggerPausedMessage.css +8 -0
  75. package/front_end/panels/timeline/StatusDialog.ts +4 -3
  76. package/front_end/panels/timeline/TimelineFlameChartNetworkDataProvider.ts +3 -16
  77. package/front_end/panels/timeline/TimelineFlameChartView.ts +64 -21
  78. package/front_end/panels/timeline/TimelinePanel.ts +71 -24
  79. package/front_end/panels/timeline/TimelineUIUtils.ts +28 -2
  80. package/front_end/panels/timeline/TimingsTrackAppender.ts +3 -1
  81. package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +1 -1
  82. package/front_end/panels/timeline/components/insights/RenderBlocking.ts +6 -4
  83. package/front_end/panels/timeline/components/sidebarInsightsTab.css +2 -0
  84. package/front_end/panels/timeline/overlays/OverlaysImpl.ts +4 -0
  85. package/front_end/panels/timeline/timelinePanel.css +8 -1
  86. package/front_end/panels/timeline/utils/EntryNodes.ts +2 -1
  87. package/front_end/third_party/acorn/estree-legacy.d.ts +2 -0
  88. package/front_end/third_party/chromium/README.chromium +1 -1
  89. package/front_end/third_party/puppeteer/README.chromium +2 -2
  90. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts +12 -0
  91. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts.map +1 -1
  92. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.js.map +1 -1
  93. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +14 -2
  94. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
  95. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
  96. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.d.ts +3 -1
  97. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.d.ts.map +1 -1
  98. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.js +6 -0
  99. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.js.map +1 -1
  100. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.d.ts +0 -1
  101. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
  102. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.js +0 -20
  103. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.js.map +1 -1
  104. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +3 -1
  105. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
  106. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +10 -14
  107. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
  108. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts +1 -0
  109. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
  110. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js +14 -0
  111. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
  112. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts +3 -1
  113. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts.map +1 -1
  114. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js +12 -0
  115. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js.map +1 -1
  116. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/EmulationManager.d.ts +1 -0
  117. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/EmulationManager.d.ts.map +1 -1
  118. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/EmulationManager.js +22 -0
  119. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/EmulationManager.js.map +1 -1
  120. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts +3 -1
  121. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
  122. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +9 -2
  123. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
  124. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  125. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
  126. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
  127. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
  128. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  129. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  130. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  131. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +26 -0
  132. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +72 -15
  133. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts +12 -0
  134. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts.map +1 -1
  135. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.js.map +1 -1
  136. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +14 -2
  137. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
  138. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
  139. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.d.ts +3 -1
  140. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.d.ts.map +1 -1
  141. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.js +6 -0
  142. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.js.map +1 -1
  143. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.d.ts +0 -1
  144. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
  145. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.js +0 -20
  146. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.js.map +1 -1
  147. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +3 -1
  148. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
  149. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +11 -15
  150. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
  151. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts +1 -0
  152. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
  153. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js +14 -0
  154. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
  155. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts +3 -1
  156. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts.map +1 -1
  157. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js +12 -0
  158. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js.map +1 -1
  159. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/EmulationManager.d.ts +1 -0
  160. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/EmulationManager.d.ts.map +1 -1
  161. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/EmulationManager.js +22 -0
  162. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/EmulationManager.js.map +1 -1
  163. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts +3 -1
  164. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts.map +1 -1
  165. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +9 -2
  166. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
  167. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
  168. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
  169. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
  170. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  171. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  172. package/front_end/third_party/puppeteer/package/lib/types.d.ts +26 -0
  173. package/front_end/third_party/puppeteer/package/package.json +1 -1
  174. package/front_end/third_party/puppeteer/package/src/api/Browser.ts +18 -0
  175. package/front_end/third_party/puppeteer/package/src/api/Page.ts +16 -2
  176. package/front_end/third_party/puppeteer/package/src/bidi/Browser.ts +13 -0
  177. package/front_end/third_party/puppeteer/package/src/bidi/HTTPRequest.ts +0 -33
  178. package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +14 -28
  179. package/front_end/third_party/puppeteer/package/src/bidi/core/BrowsingContext.ts +19 -0
  180. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +19 -0
  181. package/front_end/third_party/puppeteer/package/src/cdp/EmulationManager.ts +30 -0
  182. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +15 -6
  183. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  184. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  185. package/front_end/ui/components/icon_button/iconButton.css +3 -1
  186. package/front_end/ui/components/report_view/ReportView.ts +11 -2
  187. package/front_end/ui/components/report_view/report.css +16 -0
  188. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +202 -32
  189. package/front_end/ui/components/text_editor/config.ts +6 -6
  190. package/front_end/ui/legacy/ContextMenu.ts +11 -2
  191. package/front_end/ui/legacy/SearchableView.ts +11 -5
  192. package/front_end/ui/legacy/SplitWidget.ts +1 -1
  193. package/front_end/ui/legacy/TextPrompt.ts +1 -1
  194. package/front_end/ui/legacy/Toolbar.ts +4 -0
  195. package/front_end/ui/legacy/UIUtils.ts +0 -2
  196. package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +18 -3
  197. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +3 -3
  198. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +6 -0
  199. package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +43 -9
  200. package/front_end/ui/visual_logging/KnownContextValues.ts +13 -0
  201. package/package.json +1 -1
@@ -5,7 +5,9 @@
5
5
  import * as Host from '../../core/host/host.js';
6
6
  import * as i18n from '../../core/i18n/i18n.js';
7
7
  import * as UI from '../../ui/legacy/legacy.js';
8
- import {html, render} from '../../ui/lit/lit.js';
8
+ import {html, nothing, render} from '../../ui/lit/lit.js';
9
+
10
+ import styles from './aiCodeGenerationTeaser.css.js';
9
11
 
10
12
  const UIStringsNotTranslate = {
11
13
  /**
@@ -20,23 +22,56 @@ const UIStringsNotTranslate = {
20
22
  * Text for teaser when generating suggestion.
21
23
  */
22
24
  generating: 'Generating... (esc to cancel)',
25
+ /**
26
+ * Text for teaser for discoverability.
27
+ */
28
+ writeACommentToGenerateCode: 'Write a comment to generate code',
23
29
  } as const;
24
30
 
25
31
  const lockedString = i18n.i18n.lockedString;
32
+ const PROMOTION_ID = 'ai-code-generation';
33
+
34
+ export enum AiCodeGenerationTeaserDisplayState {
35
+ TRIGGER = 'trigger',
36
+ DISCOVERY = 'discovery',
37
+ LOADING = 'loading',
38
+ }
26
39
 
27
40
  export interface ViewInput {
28
- loading: boolean;
41
+ displayState: AiCodeGenerationTeaserDisplayState;
29
42
  }
30
43
 
31
44
  export type View = (input: ViewInput, output: object, target: HTMLElement) => void;
32
45
 
33
46
  export const DEFAULT_VIEW: View = (input, _output, target) => {
34
- const toGenerateCode = Host.Platform.isMac() ? lockedString(UIStringsNotTranslate.cmdItoGenerateCode) :
35
- lockedString(UIStringsNotTranslate.ctrlItoGenerateCode);
36
- const teaserLabel = input.loading ? lockedString(UIStringsNotTranslate.generating) : toGenerateCode;
47
+ let teaserLabel;
48
+ switch (input.displayState) {
49
+ case AiCodeGenerationTeaserDisplayState.DISCOVERY: {
50
+ const newBadge = UI.UIUtils.maybeCreateNewBadge(PROMOTION_ID);
51
+ teaserLabel = newBadge ?
52
+ html`${lockedString(UIStringsNotTranslate.writeACommentToGenerateCode)} ${newBadge}` :
53
+ nothing;
54
+ break;
55
+ }
56
+
57
+ case AiCodeGenerationTeaserDisplayState.LOADING: {
58
+ teaserLabel = html`${lockedString(UIStringsNotTranslate.generating)}`;
59
+ break;
60
+ }
61
+
62
+ case AiCodeGenerationTeaserDisplayState.TRIGGER: {
63
+ const toGenerateCode = Host.Platform.isMac() ? lockedString(UIStringsNotTranslate.cmdItoGenerateCode) :
64
+ lockedString(UIStringsNotTranslate.ctrlItoGenerateCode);
65
+ teaserLabel = html`${toGenerateCode}`;
66
+ break;
67
+ }
68
+ }
69
+
37
70
  // clang-format off
38
71
  render(
39
72
  html`
73
+ <style>${styles}</style>
74
+ <style>@scope to (devtools-widget > *) { ${UI.inspectorCommonStyles} }</style>
40
75
  <div class="ai-code-generation-teaser">
41
76
  &nbsp;${teaserLabel}
42
77
  </div>
@@ -45,10 +80,11 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
45
80
  // clang-format on
46
81
  };
47
82
 
83
+ // TODO(b/448063927): Add "Dont show again" for discovery teaser.
48
84
  export class AiCodeGenerationTeaser extends UI.Widget.Widget {
49
85
  readonly #view: View;
50
86
 
51
- #loading = false;
87
+ #displayState = AiCodeGenerationTeaserDisplayState.TRIGGER;
52
88
 
53
89
  constructor(view?: View) {
54
90
  super();
@@ -61,20 +97,20 @@ export class AiCodeGenerationTeaser extends UI.Widget.Widget {
61
97
  const output = {};
62
98
  this.#view(
63
99
  {
64
- loading: this.#loading,
100
+ displayState: this.#displayState,
65
101
  },
66
102
  output, this.contentElement);
67
103
  }
68
104
 
69
- get loading(): boolean {
70
- return this.#loading;
105
+ get displayState(): AiCodeGenerationTeaserDisplayState {
106
+ return this.#displayState;
71
107
  }
72
108
 
73
- set loading(loading: boolean) {
74
- if (loading === this.#loading) {
109
+ set displayState(displayState: AiCodeGenerationTeaserDisplayState) {
110
+ if (displayState === this.#displayState) {
75
111
  return;
76
112
  }
77
- this.#loading = loading;
113
+ this.#displayState = displayState;
78
114
  this.requestUpdate();
79
115
  }
80
116
  }
@@ -0,0 +1,14 @@
1
+ /*
2
+ * Copyright 2025 The Chromium Authors
3
+ * Use of this source code is governed by a BSD-style license that can be
4
+ * found in the LICENSE file.
5
+ */
6
+
7
+ @scope to (devtools-widget > *) {
8
+ .ai-code-generation-teaser {
9
+ .new-badge {
10
+ font-style: normal;
11
+ display: inline-block;
12
+ }
13
+ }
14
+ }
@@ -95,7 +95,7 @@ export class TypeToAllowDialog {
95
95
  }
96
96
 
97
97
  export {AiCodeCompletionTeaser} from './AiCodeCompletionTeaser.js';
98
- export {AiCodeGenerationTeaser} from './AiCodeGenerationTeaser.js';
98
+ export * as AiCodeGenerationTeaser from './AiCodeGenerationTeaser.js';
99
99
  export {AnnotationManager} from './AnnotationManager.js';
100
100
  export {FreDialog} from './FreDialog.js';
101
101
  export {GdpSignUpDialog} from './GdpSignUpDialog.js';
@@ -982,10 +982,11 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
982
982
  const renderResult = await UI.UIUtils.Renderer.render(node);
983
983
  if (renderResult) {
984
984
  this.selectableChildren.push(renderResult);
985
- const resizeObserver = new ResizeObserver(() => {
985
+ // FIXME: this should not be needed once ConsoleViewMessage is rendering
986
+ // declaratively and the tree outline auto-resizes itself.
987
+ renderResult.element.addEventListener('dimensionschanged', () => {
986
988
  this.messageResized({data: renderResult.element});
987
989
  });
988
- resizeObserver.observe(renderResult.element);
989
990
  result.appendChild(renderResult.element);
990
991
  } else {
991
992
  result.appendChild(this.formatParameterAsObject(remoteObject, false));
@@ -1185,7 +1186,7 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
1185
1186
  }
1186
1187
 
1187
1188
  matchesFilterText(filter: string): boolean {
1188
- const text = this.contentElement().deepTextContent();
1189
+ const text = this.contentElement().deepTextContent() + this.message.messageText;
1189
1190
  return text.toLowerCase().includes(filter.toLowerCase());
1190
1191
  }
1191
1192
 
@@ -221,7 +221,7 @@
221
221
  --console-color-white: #fff;
222
222
 
223
223
  &:focus {
224
- background-color: var(--sys-color-state-focus-highlight);
224
+ background-image: linear-gradient(to bottom, var(--sys-color-state-focus-highlight), var(--sys-color-state-focus-highlight));
225
225
  }
226
226
  }
227
227
 
@@ -85,6 +85,20 @@ const UIStrings = {
85
85
  */
86
86
  flexGridContainerPropertyRuleFix:
87
87
  'Try setting the {PROPERTY_NAME} on the container element or use {ALTERNATIVE_PROPERTY_NAME} instead.',
88
+ /**
89
+ * @description The messages shown in the Style pane when the user hovers over a position-anchor declaration that has no affect on a non-anchor-positioned element.
90
+ * @example {relative} POSITION
91
+ */
92
+ invalidAnchorPositioning:
93
+ 'An anchor was defined but the element was not anchor-positioned but positioned "{POSITION}".',
94
+ /**
95
+ * @description The messages shown in the Style pane when the user hovers over a position-anchor declaration that has no affect on a non-anchor-positioned element.
96
+ */
97
+ invalidAnchorPositioningFix: 'Set position to either "fixed" or "absolute".',
98
+ /**
99
+ * @description The messages shown in the Style pane when the user hovers over a position-anchor declaration that has no affect on hidden element.
100
+ */
101
+ unusedAnchorPositioning: 'An anchor was defined but the element is hidden.',
88
102
  } as const;
89
103
  const str_ = i18n.i18n.registerUIStrings('panels/elements/CSSRuleValidator.ts', UIStrings);
90
104
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -547,6 +561,29 @@ export class ZIndexValidator extends CSSRuleValidator {
547
561
  }
548
562
  }
549
563
 
564
+ export class PositionAnchorValidator extends CSSRuleValidator {
565
+ constructor() {
566
+ super(['position-anchor']);
567
+ }
568
+
569
+ override getHint(propertyName: string, computedStyles?: Map<string, string>): Hint|undefined {
570
+ const position = computedStyles?.get('position') ?? 'static';
571
+ const display = computedStyles?.get('display');
572
+
573
+ if (position !== 'absolute' && position !== 'fixed') {
574
+ return new Hint(
575
+ i18nString(UIStrings.invalidAnchorPositioning, {POSITION: position}),
576
+ i18nString(UIStrings.invalidAnchorPositioningFix));
577
+ }
578
+
579
+ if (display === 'none') {
580
+ return new Hint(i18nString(UIStrings.unusedAnchorPositioning, {POSITION: position}), null);
581
+ }
582
+
583
+ return undefined;
584
+ }
585
+ }
586
+
550
587
  /**
551
588
  * Validates if CSS width/height are having an effect on an element.
552
589
  * See "Applies to" in https://www.w3.org/TR/css-sizing-3/#propdef-width.
@@ -659,6 +696,7 @@ const CSS_RULE_VALIDATORS = [
659
696
  MulticolFlexGridValidator,
660
697
  PaddingValidator,
661
698
  PositionValidator,
699
+ PositionAnchorValidator,
662
700
  SizingValidator,
663
701
  ZIndexValidator,
664
702
  ];
@@ -44,6 +44,7 @@ import * as Badges from '../../models/badges/badges.js';
44
44
  import type * as Elements from '../../models/elements/elements.js';
45
45
  import type * as IssuesManager from '../../models/issues_manager/issues_manager.js';
46
46
  import * as TextUtils from '../../models/text_utils/text_utils.js';
47
+ import * as Workspace from '../../models/workspace/workspace.js';
47
48
  import * as CodeMirror from '../../third_party/codemirror.next/codemirror.next.js';
48
49
  import type {DirectiveResult} from '../../third_party/lit/lib/directive.js';
49
50
  import * as Adorners from '../../ui/components/adorners/adorners.js';
@@ -275,6 +276,10 @@ const UIStrings = {
275
276
  */
276
277
  startAChat: 'Start a chat',
277
278
  /**
279
+    * @description Label of an adorner next to the html node in the Elements panel.
280
+    */
281
+ viewSourceCode: 'View source code',
282
+ /**
278
283
  * @description Context menu item in Elements panel to assess visibility of an element via AI.
279
284
  */
280
285
  assessVisibility: 'Assess visibility',
@@ -378,6 +383,7 @@ export interface ViewInput {
378
383
 
379
384
  showAdAdorner: boolean;
380
385
  showContainerAdorner: boolean;
386
+ containerType?: string;
381
387
  showFlexAdorner: boolean;
382
388
  showGridAdorner: boolean;
383
389
  showGridLanesAdorner: boolean;
@@ -386,6 +392,8 @@ export interface ViewInput {
386
392
  showTopLayerAdorner: boolean;
387
393
  isSubgrid: boolean;
388
394
 
395
+ showViewSourceAdorner: boolean;
396
+ showScrollAdorner: boolean;
389
397
  adorners?: Set<Adorners.Adorner.Adorner>;
390
398
  nodeInfo?: DocumentFragment;
391
399
  topLayerIndex: number;
@@ -399,6 +407,7 @@ export interface ViewInput {
399
407
  onMediaAdornerClick: (e: Event) => void;
400
408
  onPopoverAdornerClick: (e: Event) => void;
401
409
  onTopLayerAdornerClick: (e: Event) => void;
410
+ onViewSourceAdornerClick: () => void;
402
411
  }
403
412
 
404
413
  export interface ViewOutput {
@@ -429,6 +438,8 @@ function adornerRef(input: ViewInput): DirectiveResult<typeof Lit.Directives.Ref
429
438
  export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLElement): void => {
430
439
  const adAdornerConfig =
431
440
  ElementsComponents.AdornerManager.getRegisteredAdorner(ElementsComponents.AdornerManager.RegisteredAdorners.AD);
441
+ const viewSourceAdornerConfig = ElementsComponents.AdornerManager.getRegisteredAdorner(
442
+ ElementsComponents.AdornerManager.RegisteredAdorners.VIEW_SOURCE);
432
443
  const containerAdornerConfig = ElementsComponents.AdornerManager.getRegisteredAdorner(
433
444
  ElementsComponents.AdornerManager.RegisteredAdorners.CONTAINER);
434
445
  const flexAdornerConfig =
@@ -445,9 +456,11 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
445
456
  ElementsComponents.AdornerManager.RegisteredAdorners.POPOVER);
446
457
  const topLayerAdornerConfig = ElementsComponents.AdornerManager.getRegisteredAdorner(
447
458
  ElementsComponents.AdornerManager.RegisteredAdorners.TOP_LAYER);
459
+ const scrollAdornerConfig = ElementsComponents.AdornerManager.getRegisteredAdorner(
460
+ ElementsComponents.AdornerManager.RegisteredAdorners.SCROLL);
448
461
  const hasAdorners = input.adorners?.size || input.showAdAdorner || input.showContainerAdorner ||
449
462
  input.showFlexAdorner || input.showGridAdorner || input.showGridLanesAdorner || input.showMediaAdorner ||
450
- input.showPopoverAdorner || input.showTopLayerAdorner;
463
+ input.showPopoverAdorner || input.showTopLayerAdorner || input.showViewSourceAdorner || input.showScrollAdorner;
451
464
  // clang-format off
452
465
  render(html`
453
466
  <div ${ref(el => { output.contentElement = el as HTMLElement; })}>
@@ -463,6 +476,13 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
463
476
  ${adornerRef(input)}>
464
477
  <span>${adAdornerConfig.name}</span>
465
478
  </devtools-adorner>` : nothing}
479
+ ${input.showViewSourceAdorner ? html`<devtools-adorner
480
+ .data=${{name: viewSourceAdornerConfig.name, jslogContext: viewSourceAdornerConfig.name}}
481
+ aria-label=${i18nString(UIStrings.viewSourceCode)}
482
+ @click=${input.onViewSourceAdornerClick}
483
+ ${adornerRef(input)}>
484
+ <span>${viewSourceAdornerConfig.name}</span>
485
+ </devtools-adorner>` : nothing}
466
486
  ${input.showContainerAdorner ? html`<devtools-adorner
467
487
  class=clickable
468
488
  role=button
@@ -480,7 +500,10 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
480
500
  }
481
501
  }}
482
502
  ${adornerRef(input)}>
483
- <span>${containerAdornerConfig.name}</span>
503
+ <span class="adorner-with-icon">
504
+ <devtools-icon name="container"></devtools-icon>
505
+ <span>${input.containerType}</span>
506
+ </span>
484
507
  </devtools-adorner>`: nothing}
485
508
  ${input.showFlexAdorner ? html`<devtools-adorner
486
509
  class=clickable
@@ -602,6 +625,13 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
602
625
  ${repeat(Array.from((input.adorners ?? new Set()).values()).sort(adornerComparator), adorner => {
603
626
  return adorner;
604
627
  })}
628
+ ${input.showScrollAdorner ? html`<devtools-adorner
629
+ class="scroll"
630
+ .data=${{name: scrollAdornerConfig.name, jslogContext: scrollAdornerConfig.name}}
631
+ aria-label=${i18nString(UIStrings.elementHasScrollableOverflow)}
632
+ ${adornerRef(input)}>
633
+ <span>${scrollAdornerConfig.name}</span>
634
+ </devtools-adorner>` : nothing}
605
635
  </div>`: nothing}
606
636
  </div>
607
637
  `, target);
@@ -673,8 +703,6 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
673
703
  };
674
704
  void this.updateStyleAdorners();
675
705
 
676
- void this.updateScrollAdorner();
677
-
678
706
  void this.#updateAdorners();
679
707
  }
680
708
  this.expandAllButtonElement = null;
@@ -695,34 +723,6 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
695
723
  if (this.nodeInternal.detached && !this.isClosingTag()) {
696
724
  this.listItemNode.setAttribute('title', 'Detached Tree Node');
697
725
  }
698
-
699
- node.domModel().overlayModel().addEventListener(
700
- SDK.OverlayModel.Events.PERSISTENT_CONTAINER_QUERY_OVERLAY_STATE_CHANGED, event => {
701
- const {nodeId: eventNodeId, enabled} = event.data;
702
- if (eventNodeId !== node.id) {
703
- return;
704
- }
705
- this.#containerAdornerActive = enabled;
706
- this.performUpdate();
707
- });
708
- node.domModel().overlayModel().addEventListener(
709
- SDK.OverlayModel.Events.PERSISTENT_FLEX_CONTAINER_OVERLAY_STATE_CHANGED, event => {
710
- const {nodeId: eventNodeId, enabled} = event.data;
711
- if (eventNodeId !== node.id) {
712
- return;
713
- }
714
- this.#flexAdornerActive = enabled;
715
- this.performUpdate();
716
- });
717
- node.domModel().overlayModel().addEventListener(
718
- SDK.OverlayModel.Events.PERSISTENT_GRID_OVERLAY_STATE_CHANGED, event => {
719
- const {nodeId: eventNodeId, enabled} = event.data;
720
- if (eventNodeId !== node.id) {
721
- return;
722
- }
723
- this.#gridAdornerActive = enabled;
724
- this.performUpdate();
725
- });
726
726
  }
727
727
 
728
728
  static animateOnDOMUpdate(treeElement: ElementsTreeElement): void {
@@ -788,7 +788,8 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
788
788
  containerAdornerActive: this.#containerAdornerActive,
789
789
  adorners: !this.isClosingTag() ? this.#adorners : undefined,
790
790
  showAdAdorner: this.nodeInternal.isAdFrameNode(),
791
- showContainerAdorner: Boolean(this.#layout?.isContainer) && !this.isClosingTag(),
791
+ showContainerAdorner: Boolean(this.#layout?.containerType) && !this.isClosingTag(),
792
+ containerType: this.#layout?.containerType,
792
793
  showFlexAdorner: Boolean(this.#layout?.isFlex) && !this.isClosingTag(),
793
794
  flexAdornerActive: this.#flexAdornerActive,
794
795
  showGridAdorner: Boolean(this.#layout?.isGrid) && !this.isClosingTag(),
@@ -800,8 +801,13 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
800
801
  gridAdornerActive: this.#gridAdornerActive,
801
802
  popoverAdornerActive: this.#popoverAdornerActive,
802
803
  isSubgrid: Boolean(this.#layout?.isSubgrid),
804
+ showViewSourceAdorner: this.nodeInternal.isRootNode() && isOpeningTag(this.tagTypeContext),
805
+ showScrollAdorner: ((this.node().nodeName() === 'HTML' && this.node().ownerDocument?.isScrollable()) ||
806
+ (this.node().nodeName() !== '#document' && this.node().isScrollable())) &&
807
+ !this.isClosingTag(),
803
808
  nodeInfo: this.#nodeInfo,
804
809
  topLayerIndex: this.node().topLayerIndex(),
810
+ onViewSourceAdornerClick: this.revealHTMLInSources.bind(this),
805
811
  onGutterClick: this.showContextMenu.bind(this),
806
812
  onAdornerAdded: adorner => {
807
813
  ElementsPanel.instance().registerAdorner(adorner);
@@ -1106,6 +1112,18 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
1106
1112
  if (this.treeOutline && !this.isClosingTag()) {
1107
1113
  this.treeOutline.treeElementByNode.set(this.nodeInternal, this);
1108
1114
  this.nodeInternal.addEventListener(SDK.DOMModel.DOMNodeEvents.TOP_LAYER_INDEX_CHANGED, this.performUpdate, this);
1115
+ this.nodeInternal.addEventListener(
1116
+ SDK.DOMModel.DOMNodeEvents.SCROLLABLE_FLAG_UPDATED, this.#onScrollableFlagUpdated, this);
1117
+ const overlayModel = this.nodeInternal.domModel().overlayModel();
1118
+ overlayModel.addEventListener(
1119
+ SDK.OverlayModel.Events.PERSISTENT_CONTAINER_QUERY_OVERLAY_STATE_CHANGED,
1120
+ this.#onPersistentContainerQueryOverlayStateChanged, this);
1121
+ overlayModel.addEventListener(
1122
+ SDK.OverlayModel.Events.PERSISTENT_FLEX_CONTAINER_OVERLAY_STATE_CHANGED,
1123
+ this.#onPersistentFlexContainerOverlayStateChanged, this);
1124
+ overlayModel.addEventListener(
1125
+ SDK.OverlayModel.Events.PERSISTENT_GRID_OVERLAY_STATE_CHANGED, this.#onPersistentGridOverlayStateChanged,
1126
+ this);
1109
1127
  }
1110
1128
  }
1111
1129
 
@@ -1117,6 +1135,51 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
1117
1135
  this.treeOutline.treeElementByNode.delete(this.nodeInternal);
1118
1136
  }
1119
1137
  this.nodeInternal.removeEventListener(SDK.DOMModel.DOMNodeEvents.TOP_LAYER_INDEX_CHANGED, this.performUpdate, this);
1138
+ this.nodeInternal.removeEventListener(
1139
+ SDK.DOMModel.DOMNodeEvents.SCROLLABLE_FLAG_UPDATED, this.#onScrollableFlagUpdated, this);
1140
+ const overlayModel = this.nodeInternal.domModel().overlayModel();
1141
+ overlayModel.removeEventListener(
1142
+ SDK.OverlayModel.Events.PERSISTENT_CONTAINER_QUERY_OVERLAY_STATE_CHANGED,
1143
+ this.#onPersistentContainerQueryOverlayStateChanged, this);
1144
+ overlayModel.removeEventListener(
1145
+ SDK.OverlayModel.Events.PERSISTENT_FLEX_CONTAINER_OVERLAY_STATE_CHANGED,
1146
+ this.#onPersistentFlexContainerOverlayStateChanged, this);
1147
+ overlayModel.removeEventListener(
1148
+ SDK.OverlayModel.Events.PERSISTENT_GRID_OVERLAY_STATE_CHANGED, this.#onPersistentGridOverlayStateChanged, this);
1149
+ }
1150
+
1151
+ #onScrollableFlagUpdated(): void {
1152
+ void this.#updateAdorners();
1153
+ }
1154
+
1155
+ #onPersistentContainerQueryOverlayStateChanged(
1156
+ event: Common.EventTarget.EventTargetEvent<SDK.OverlayModel.ChangedNodeId>): void {
1157
+ const {nodeId: eventNodeId, enabled} = event.data;
1158
+ if (eventNodeId !== this.nodeInternal.id) {
1159
+ return;
1160
+ }
1161
+ this.#containerAdornerActive = enabled;
1162
+ this.performUpdate();
1163
+ }
1164
+
1165
+ #onPersistentFlexContainerOverlayStateChanged(
1166
+ event: Common.EventTarget.EventTargetEvent<SDK.OverlayModel.ChangedNodeId>): void {
1167
+ const {nodeId: eventNodeId, enabled} = event.data;
1168
+ if (eventNodeId !== this.nodeInternal.id) {
1169
+ return;
1170
+ }
1171
+ this.#flexAdornerActive = enabled;
1172
+ this.performUpdate();
1173
+ }
1174
+
1175
+ #onPersistentGridOverlayStateChanged(event: Common.EventTarget.EventTargetEvent<SDK.OverlayModel.ChangedNodeId>):
1176
+ void {
1177
+ const {nodeId: eventNodeId, enabled} = event.data;
1178
+ if (eventNodeId !== this.nodeInternal.id) {
1179
+ return;
1180
+ }
1181
+ this.#gridAdornerActive = enabled;
1182
+ this.performUpdate();
1120
1183
  }
1121
1184
 
1122
1185
  override onattach(): void {
@@ -1291,6 +1354,17 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
1291
1354
  this.treeOutline && void this.treeOutline.showContextMenu(this, event);
1292
1355
  }
1293
1356
 
1357
+ private revealHTMLInSources(): void {
1358
+ const frameOwnerId = this.nodeInternal.frameOwnerFrameId();
1359
+ if (frameOwnerId) {
1360
+ const frame = SDK.FrameManager.FrameManager.instance().getFrame(frameOwnerId);
1361
+ if (frame) {
1362
+ const sourceCode = Workspace.Workspace.WorkspaceImpl.instance().uiSourceCodeForURL(frame.url);
1363
+ void Common.Revealer.reveal(sourceCode);
1364
+ }
1365
+ }
1366
+ }
1367
+
1294
1368
  async populateTagContextMenu(contextMenu: UI.ContextMenu.ContextMenu, event: Event): Promise<void> {
1295
1369
  // Add attribute-related actions.
1296
1370
  const treeElement =
@@ -1463,7 +1537,7 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
1463
1537
  ],
1464
1538
  },
1465
1539
  {
1466
- condition: (props: SDK.CSSModel.LayoutProperties|null): boolean => Boolean(props?.isContainer),
1540
+ condition: (props: SDK.CSSModel.LayoutProperties|null): boolean => Boolean(props?.containerType),
1467
1541
  items: [
1468
1542
  {
1469
1543
  label: i18nString(UIStrings.explainContainerQueries),
@@ -3029,30 +3103,6 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
3029
3103
  this.#adorners.add(adorner);
3030
3104
  }
3031
3105
 
3032
- updateScrollAdorner(): void {
3033
- if (!isOpeningTag(this.tagTypeContext)) {
3034
- return;
3035
- }
3036
- const scrollAdorner =
3037
- this.#adorners.values().find(x => x.name === ElementsComponents.AdornerManager.RegisteredAdorners.SCROLL);
3038
- // Check if the node is scrollable, or if it's the <html> element and the document is scrollable
3039
- // because the top-level document (#document) doesn't have a corresponding tree element.
3040
- const needsAScrollAdorner = (this.node().nodeName() === 'HTML' && this.node().ownerDocument?.isScrollable()) ||
3041
- (this.node().nodeName() !== '#document' && this.node().isScrollable());
3042
- if (needsAScrollAdorner && !scrollAdorner) {
3043
- this.pushScrollAdorner();
3044
- } else if (!needsAScrollAdorner && scrollAdorner) {
3045
- this.removeAdorner(scrollAdorner);
3046
- }
3047
- }
3048
-
3049
- pushScrollAdorner(): void {
3050
- const config = ElementsComponents.AdornerManager.getRegisteredAdorner(
3051
- ElementsComponents.AdornerManager.RegisteredAdorners.SCROLL);
3052
- const adorner = this.adorn(config);
3053
- UI.Tooltip.Tooltip.install(adorner, i18nString(UIStrings.elementHasScrollableOverflow));
3054
- adorner.classList.add('scroll');
3055
- }
3056
3106
  }
3057
3107
 
3058
3108
  export const InitialChildrenLimit = 500;
@@ -1526,7 +1526,6 @@ export class ElementsTreeOutline extends
1526
1526
  domModel.addEventListener(SDK.DOMModel.Events.DocumentUpdated, this.documentUpdated, this);
1527
1527
  domModel.addEventListener(SDK.DOMModel.Events.ChildNodeCountUpdated, this.childNodeCountUpdated, this);
1528
1528
  domModel.addEventListener(SDK.DOMModel.Events.DistributedNodesChanged, this.distributedNodesChanged, this);
1529
- domModel.addEventListener(SDK.DOMModel.Events.ScrollableFlagUpdated, this.scrollableFlagUpdated, this);
1530
1529
  domModel.addEventListener(
1531
1530
  SDK.DOMModel.Events.AffectedByStartingStylesFlagUpdated, this.affectedByStartingStylesFlagUpdated, this);
1532
1531
  domModel.addEventListener(SDK.DOMModel.Events.AdoptedStyleSheetsModified, this.adoptedStyleSheetsModified, this);
@@ -1542,7 +1541,6 @@ export class ElementsTreeOutline extends
1542
1541
  domModel.removeEventListener(SDK.DOMModel.Events.DocumentUpdated, this.documentUpdated, this);
1543
1542
  domModel.removeEventListener(SDK.DOMModel.Events.ChildNodeCountUpdated, this.childNodeCountUpdated, this);
1544
1543
  domModel.removeEventListener(SDK.DOMModel.Events.DistributedNodesChanged, this.distributedNodesChanged, this);
1545
- domModel.removeEventListener(SDK.DOMModel.Events.ScrollableFlagUpdated, this.scrollableFlagUpdated, this);
1546
1544
  domModel.removeEventListener(
1547
1545
  SDK.DOMModel.Events.AffectedByStartingStylesFlagUpdated, this.affectedByStartingStylesFlagUpdated, this);
1548
1546
  domModel.removeEventListener(SDK.DOMModel.Events.AdoptedStyleSheetsModified, this.adoptedStyleSheetsModified, this);
@@ -2020,21 +2018,6 @@ export class ElementsTreeOutline extends
2020
2018
  }
2021
2019
  }
2022
2020
 
2023
- private scrollableFlagUpdated(event: Common.EventTarget.EventTargetEvent<{node: SDK.DOMModel.DOMNode}>): void {
2024
- let {node} = event.data;
2025
- if (node.nodeName() === '#document') {
2026
- // We show the scroll badge of the document on the <html> element.
2027
- if (!node.ownerDocument?.documentElement) {
2028
- return;
2029
- }
2030
- node = node.ownerDocument.documentElement;
2031
- }
2032
- const treeElement = this.treeElementByNode.get(node);
2033
- if (treeElement && isOpeningTag(treeElement.tagTypeContext)) {
2034
- void treeElement.updateScrollAdorner();
2035
- }
2036
- }
2037
-
2038
2021
  private affectedByStartingStylesFlagUpdated(event: Common.EventTarget.EventTargetEvent<{node: SDK.DOMModel.DOMNode}>):
2039
2022
  void {
2040
2023
  const {node} = event.data;
@@ -33,7 +33,7 @@
33
33
  */
34
34
 
35
35
  import * as SDK from '../../core/sdk/sdk.js';
36
- import type * as UI from '../../ui/legacy/legacy.js';
36
+ import * as UI from '../../ui/legacy/legacy.js';
37
37
 
38
38
  import {ElementsTreeOutline} from './ElementsTreeOutline.js';
39
39
 
@@ -75,6 +75,12 @@ export class Renderer implements UI.UIUtils.Renderer {
75
75
  if (options?.expand) {
76
76
  treeOutline.firstChild()?.expand();
77
77
  }
78
+ const dispatchDimensionChange = (): void => {
79
+ treeOutline.element.dispatchEvent(new CustomEvent('dimensionschanged'));
80
+ };
81
+ treeOutline.addEventListener(UI.TreeOutline.Events.ElementAttached, dispatchDimensionChange);
82
+ treeOutline.addEventListener(UI.TreeOutline.Events.ElementExpanded, dispatchDimensionChange);
83
+ treeOutline.addEventListener(UI.TreeOutline.Events.ElementCollapsed, dispatchDimensionChange);
78
84
  return {
79
85
  element: treeOutline.element,
80
86
  forceSelect: treeOutline.forceSelect.bind(treeOutline),
@@ -482,6 +482,10 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
482
482
 
483
483
  private onFilterChanged(event: Common.EventTarget.EventTargetEvent<string>): void {
484
484
  const regex = event.data ? new RegExp(Platform.StringUtilities.escapeForRegExp(event.data), 'i') : null;
485
+ this.setFilter(regex);
486
+ }
487
+
488
+ setFilter(regex: RegExp|null): void {
485
489
  this.lastFilterChange = Date.now();
486
490
  this.#filterRegex = regex;
487
491
  this.updateFilter();
@@ -1036,6 +1040,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1036
1040
  let sectionIdx = 0;
1037
1041
  let lastParentNode: SDK.DOMModel.DOMNode|null = null;
1038
1042
 
1043
+ let lastLayerParent: SectionBlock|undefined;
1039
1044
  let lastLayers: SDK.CSSLayer.CSSLayer[]|null = null;
1040
1045
  let sawLayers = false;
1041
1046
 
@@ -1046,6 +1051,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1046
1051
  if ((layers.length || lastLayers) && lastLayers !== layers) {
1047
1052
  const block = SectionBlock.createLayerBlock(parentRule);
1048
1053
  blocks.push(block);
1054
+ lastLayerParent?.childBlocks.push(block);
1049
1055
  sawLayers = true;
1050
1056
  lastLayers = layers;
1051
1057
  }
@@ -1055,12 +1061,12 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1055
1061
  // We disable the layer widget initially. If we see a layer in
1056
1062
  // the matched styles we reenable the button.
1057
1063
  LayersWidget.ButtonProvider.instance().item().setVisible(false);
1058
-
1059
1064
  for (const style of matchedStyles.nodeStyles()) {
1060
1065
  const parentNode = matchedStyles.isInherited(style) ? matchedStyles.nodeForStyle(style) : null;
1061
1066
  if (parentNode && parentNode !== lastParentNode) {
1062
1067
  lastParentNode = parentNode;
1063
1068
  const block = await SectionBlock.createInheritedNodeBlock(lastParentNode);
1069
+ lastLayerParent = block;
1064
1070
  blocks.push(block);
1065
1071
  }
1066
1072
 
@@ -1078,6 +1084,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1078
1084
  });
1079
1085
  }
1080
1086
  }
1087
+ lastLayerParent = undefined;
1081
1088
 
1082
1089
  const customHighlightPseudoRulesets: Array<{
1083
1090
  highlightName: string | null,
@@ -1130,9 +1137,11 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
1130
1137
  if (parentNode) {
1131
1138
  const block =
1132
1139
  await SectionBlock.createInheritedPseudoTypeBlock(pseudo.pseudoType, pseudo.highlightName, parentNode);
1140
+ lastLayerParent = block;
1133
1141
  blocks.push(block);
1134
1142
  } else {
1135
1143
  const block = SectionBlock.createPseudoTypeBlock(pseudo.pseudoType, pseudo.highlightName);
1144
+ lastLayerParent = block;
1136
1145
  blocks.push(block);
1137
1146
  }
1138
1147
  }
@@ -1503,6 +1512,7 @@ const MAX_LINK_LENGTH = 23;
1503
1512
  export class SectionBlock {
1504
1513
  readonly #titleElement: Element|null;
1505
1514
  sections: StylePropertiesSection[];
1515
+ childBlocks: SectionBlock[] = [];
1506
1516
  #expanded = false;
1507
1517
  #icon: Icon|undefined;
1508
1518
  constructor(titleElement: Element|null, expandable?: boolean, expandedByDefault?: boolean) {
@@ -1634,14 +1644,15 @@ export class SectionBlock {
1634
1644
  }
1635
1645
 
1636
1646
  updateFilter(): number {
1637
- let hasAnyVisibleSection = false;
1638
1647
  let numVisibleSections = 0;
1648
+ for (const childBlock of this.childBlocks) {
1649
+ numVisibleSections += childBlock.updateFilter();
1650
+ }
1639
1651
  for (const section of this.sections) {
1640
1652
  numVisibleSections += section.updateFilter() ? 1 : 0;
1641
- hasAnyVisibleSection = section.updateFilter() || hasAnyVisibleSection;
1642
1653
  }
1643
1654
  if (this.#titleElement) {
1644
- this.#titleElement.classList.toggle('hidden', !hasAnyVisibleSection);
1655
+ this.#titleElement.classList.toggle('hidden', numVisibleSections === 0);
1645
1656
  }
1646
1657
  return numVisibleSections;
1647
1658
  }