chrome-devtools-frontend 1.0.1547147 → 1.0.1548870

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 (212) hide show
  1. package/.stylelintrc.json +5 -1
  2. package/docs/contributing/infrastructure.md +2 -2
  3. package/eslint.config.mjs +3 -2
  4. package/front_end/Images/generate-css-vars.js +1 -1
  5. package/front_end/core/common/common.ts +0 -2
  6. package/front_end/core/i18n/collect-ui-strings.js +1 -1
  7. package/front_end/core/i18n/generate-locales-js.js +1 -1
  8. package/front_end/core/platform/HostRuntime.ts +14 -7
  9. package/front_end/core/platform/api/HostRuntime.ts +28 -3
  10. package/front_end/core/platform/browser/HostRuntime.ts +66 -5
  11. package/front_end/core/platform/node/HostRuntime.ts +76 -4
  12. package/front_end/core/sdk/AnimationModel.ts +1 -1
  13. package/front_end/core/sdk/CSSModel.ts +1 -1
  14. package/front_end/core/sdk/CSSProperty.ts +1 -1
  15. package/front_end/core/sdk/CSSPropertyParserMatchers.ts +1 -1
  16. package/front_end/core/sdk/ConsoleModel.ts +1 -1
  17. package/front_end/core/sdk/Cookie.ts +1 -1
  18. package/front_end/core/sdk/DOMModel.ts +2 -2
  19. package/front_end/core/sdk/DebuggerModel.ts +1 -1
  20. package/front_end/core/sdk/NetworkManager.ts +6 -0
  21. package/front_end/core/sdk/PreloadingModel.ts +1 -1
  22. package/front_end/core/sdk/RemoteObject.ts +1 -1
  23. package/front_end/core/sdk/ResourceTreeModel.ts +1 -1
  24. package/front_end/core/sdk/Script.ts +4 -4
  25. package/front_end/entrypoints/formatter_worker/HTMLFormatter.ts +2 -2
  26. package/front_end/entrypoints/formatter_worker/JavaScriptFormatter.ts +15 -18
  27. package/front_end/entrypoints/formatter_worker/formatter_worker-entrypoint.ts +8 -5
  28. package/front_end/entrypoints/main/ExecutionContextSelector.ts +1 -1
  29. package/front_end/entrypoints/main/MainImpl.ts +2 -2
  30. package/front_end/generated/Deprecation.ts +19 -0
  31. package/front_end/generated/InspectorBackendCommands.ts +4 -3
  32. package/front_end/generated/SupportedCSSProperties.js +13 -13
  33. package/front_end/generated/protocol-mapping.d.ts +2 -0
  34. package/front_end/generated/protocol-proxy-api.d.ts +4 -0
  35. package/front_end/generated/protocol.ts +16 -27
  36. package/front_end/models/ai_assistance/AiConversation.ts +104 -24
  37. package/front_end/models/ai_assistance/BuiltInAi.ts +131 -134
  38. package/front_end/models/ai_assistance/ChangeManager.ts +9 -0
  39. package/front_end/models/ai_assistance/ConversationHandler.ts +23 -48
  40. package/front_end/models/ai_assistance/agents/AiAgent.ts +8 -5
  41. package/front_end/models/ai_assistance/agents/StylingAgent.ts +0 -10
  42. package/front_end/models/formatter/FormatterWorkerPool.ts +9 -7
  43. package/front_end/models/har/Importer.ts +1 -1
  44. package/front_end/models/issues_manager/ContrastCheckTrigger.ts +1 -1
  45. package/front_end/models/persistence/AutomaticFileSystemManager.ts +1 -1
  46. package/front_end/panels/accessibility/AccessibilityNodeView.ts +1 -1
  47. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +80 -153
  48. package/front_end/panels/ai_assistance/components/ChatView.ts +54 -31
  49. package/front_end/panels/application/ExtensionStorageModel.ts +1 -1
  50. package/front_end/panels/application/FrameDetailsView.ts +62 -34
  51. package/front_end/panels/application/ServiceWorkerCacheViews.ts +1 -1
  52. package/front_end/panels/application/components/components.ts +0 -2
  53. package/front_end/panels/console/ConsoleInsightTeaser.ts +166 -100
  54. package/front_end/panels/console/ConsolePrompt.ts +1 -1
  55. package/front_end/panels/console/ConsoleViewMessage.ts +77 -29
  56. package/front_end/panels/console/ConsoleViewport.ts +1 -1
  57. package/front_end/panels/console/consoleInsightTeaser.css +1 -0
  58. package/front_end/panels/coverage/CoverageModel.ts +2 -2
  59. package/front_end/panels/elements/ElementsPanel.ts +1 -1
  60. package/front_end/panels/elements/ElementsTreeOutline.ts +17 -7
  61. package/front_end/panels/elements/NodeStackTraceWidget.ts +6 -5
  62. package/front_end/panels/elements/StylePropertyTreeElement.ts +1 -2
  63. package/front_end/panels/explain/components/ConsoleInsight.ts +1 -1
  64. package/front_end/panels/network/RequestConditionsDrawer.ts +64 -20
  65. package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +1 -1
  66. package/front_end/panels/profiler/HeapSnapshotProxy.ts +15 -14
  67. package/front_end/panels/recorder/components/StepEditor.ts +1 -1
  68. package/front_end/panels/security/SecurityPanelSidebar.ts +1 -3
  69. package/front_end/panels/settings/KeybindsSettingsTab.ts +1 -1
  70. package/front_end/panels/sources/CSSPlugin.ts +1 -1
  71. package/front_end/panels/sources/DebuggerPlugin.ts +2 -2
  72. package/front_end/panels/sources/NavigatorView.ts +1 -1
  73. package/front_end/panels/sources/SourcesSearchScope.ts +1 -1
  74. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +10 -2
  75. package/front_end/panels/timeline/TimelineFlameChartView.ts +1 -1
  76. package/front_end/panels/timeline/TimelinePanel.ts +7 -7
  77. package/front_end/panels/timeline/TimelineUIUtils.ts +3 -1
  78. package/front_end/panels/timeline/enable-easter-egg.js +1 -1
  79. package/front_end/panels/timeline/utils/Treemap.ts +1 -1
  80. package/front_end/third_party/chromium/README.chromium +1 -1
  81. package/front_end/third_party/puppeteer/README.chromium +2 -2
  82. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/DeviceRequestPrompt.d.ts +66 -0
  83. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/DeviceRequestPrompt.d.ts.map +1 -0
  84. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/DeviceRequestPrompt.js +57 -0
  85. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/DeviceRequestPrompt.js.map +1 -0
  86. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Frame.d.ts +1 -1
  87. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Frame.d.ts.map +1 -1
  88. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Frame.js.map +1 -1
  89. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +2 -2
  90. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
  91. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
  92. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/api.d.ts +1 -0
  93. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/api.d.ts.map +1 -1
  94. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/api.js +1 -0
  95. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/api.js.map +1 -1
  96. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
  97. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.js +1 -6
  98. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.js.map +1 -1
  99. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +0 -4
  100. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
  101. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +18 -23
  102. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
  103. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts +2 -0
  104. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
  105. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js +16 -0
  106. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
  107. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/DeviceRequestPrompt.d.ts +4 -62
  108. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/DeviceRequestPrompt.d.ts.map +1 -1
  109. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/DeviceRequestPrompt.js +9 -73
  110. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/DeviceRequestPrompt.js.map +1 -1
  111. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Frame.d.ts +1 -1
  112. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Frame.d.ts.map +1 -1
  113. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Frame.js.map +1 -1
  114. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts +1 -1
  115. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
  116. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +3 -3
  117. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
  118. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/ConsoleMessage.d.ts +8 -1
  119. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/ConsoleMessage.d.ts.map +1 -1
  120. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/ConsoleMessage.js +11 -1
  121. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/ConsoleMessage.js.map +1 -1
  122. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  123. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
  124. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
  125. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
  126. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  127. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  128. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  129. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +9 -10
  130. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +80 -81
  131. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/DeviceRequestPrompt.d.ts +66 -0
  132. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/DeviceRequestPrompt.d.ts.map +1 -0
  133. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/DeviceRequestPrompt.js +52 -0
  134. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/DeviceRequestPrompt.js.map +1 -0
  135. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Frame.d.ts +1 -1
  136. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Frame.d.ts.map +1 -1
  137. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Frame.js.map +1 -1
  138. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +2 -2
  139. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
  140. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
  141. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/api.d.ts +1 -0
  142. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/api.d.ts.map +1 -1
  143. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/api.js +1 -0
  144. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/api.js.map +1 -1
  145. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
  146. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.js +1 -6
  147. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.js.map +1 -1
  148. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +0 -4
  149. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
  150. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +18 -23
  151. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
  152. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts +2 -0
  153. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
  154. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js +16 -0
  155. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
  156. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/DeviceRequestPrompt.d.ts +4 -62
  157. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/DeviceRequestPrompt.d.ts.map +1 -1
  158. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/DeviceRequestPrompt.js +6 -69
  159. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/DeviceRequestPrompt.js.map +1 -1
  160. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Frame.d.ts +1 -1
  161. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Frame.d.ts.map +1 -1
  162. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Frame.js.map +1 -1
  163. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts +1 -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 +3 -3
  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/common/ConsoleMessage.d.ts +8 -1
  168. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/ConsoleMessage.d.ts.map +1 -1
  169. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/ConsoleMessage.js +11 -1
  170. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/ConsoleMessage.js.map +1 -1
  171. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
  172. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
  173. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
  174. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  175. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  176. package/front_end/third_party/puppeteer/package/lib/types.d.ts +9 -10
  177. package/front_end/third_party/puppeteer/package/package.json +3 -3
  178. package/front_end/third_party/puppeteer/package/src/api/DeviceRequestPrompt.ts +79 -0
  179. package/front_end/third_party/puppeteer/package/src/api/Frame.ts +1 -1
  180. package/front_end/third_party/puppeteer/package/src/api/Page.ts +2 -2
  181. package/front_end/third_party/puppeteer/package/src/api/api.ts +1 -0
  182. package/front_end/third_party/puppeteer/package/src/bidi/HTTPRequest.ts +1 -9
  183. package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +21 -31
  184. package/front_end/third_party/puppeteer/package/src/bidi/core/BrowsingContext.ts +18 -0
  185. package/front_end/third_party/puppeteer/package/src/cdp/DeviceRequestPrompt.ts +6 -72
  186. package/front_end/third_party/puppeteer/package/src/cdp/Frame.ts +2 -4
  187. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +7 -2
  188. package/front_end/third_party/puppeteer/package/src/common/ConsoleMessage.ts +14 -0
  189. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  190. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  191. package/front_end/third_party/puppeteer/puppeteer-tsconfig.json +1 -0
  192. package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +4 -0
  193. package/front_end/ui/components/text_editor/javascript.ts +1 -1
  194. package/front_end/ui/legacy/ListWidget.ts +51 -18
  195. package/front_end/ui/legacy/ReportView.ts +1 -1
  196. package/front_end/ui/legacy/TabbedPane.ts +3 -3
  197. package/front_end/ui/legacy/Treeoutline.ts +1 -1
  198. package/front_end/ui/legacy/components/color_picker/ContrastInfo.ts +1 -1
  199. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +3 -2
  200. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +87 -111
  201. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +1 -2
  202. package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +40 -11
  203. package/front_end/ui/legacy/components/utils/jsUtils.css +28 -0
  204. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
  205. package/front_end/ui/visual_logging/LoggingConfig.ts +2 -1
  206. package/inspector_overlay/tool_window_controls.ts +4 -1
  207. package/mcp/mcp.ts +1 -1
  208. package/package.json +2 -3
  209. package/front_end/core/common/Worker.ts +0 -60
  210. package/front_end/panels/application/components/StackTrace.ts +0 -238
  211. package/front_end/panels/application/components/stackTraceLinkButton.css +0 -16
  212. package/front_end/panels/application/components/stackTraceRow.css +0 -50
@@ -6,15 +6,12 @@ import * as Host from '../../core/host/host.js';
6
6
  import * as Root from '../../core/root/root.js';
7
7
 
8
8
  let builtInAiInstance: BuiltInAi|undefined;
9
- let availability: LanguageModelAvailability|undefined;
10
- let hasGpu: boolean|undefined;
11
- let isFirstRun = true;
12
9
 
13
10
  export interface LanguageModel {
14
11
  promptStreaming: (arg0: string, opts?: {
15
12
  signal?: AbortSignal,
16
13
  }) => AsyncGenerator<string>;
17
- clone: () => LanguageModel;
14
+ clone: () => Promise<LanguageModel>;
18
15
  destroy: () => void;
19
16
  }
20
17
 
@@ -27,155 +24,112 @@ export const enum LanguageModelAvailability {
27
24
  }
28
25
 
29
26
  export class BuiltInAi {
30
- #consoleInsightsSession: LanguageModel;
27
+ #availability: LanguageModelAvailability|null = null;
28
+ #hasGpu: boolean;
29
+ #consoleInsightsSession?: LanguageModel;
30
+ initDoneForTesting: Promise<void>;
31
31
 
32
- static async getLanguageModelAvailability(): Promise<LanguageModelAvailability> {
32
+ static instance(): BuiltInAi {
33
+ if (builtInAiInstance === undefined) {
34
+ builtInAiInstance = new BuiltInAi();
35
+ }
36
+ return builtInAiInstance;
37
+ }
38
+
39
+ constructor() {
40
+ this.#hasGpu = this.#isGpuAvailable();
41
+ this.initDoneForTesting =
42
+ this.getLanguageModelAvailability().then(() => this.initialize()).then(() => this.#sendAvailabilityMetrics());
43
+ }
44
+
45
+ async getLanguageModelAvailability(): Promise<LanguageModelAvailability> {
33
46
  if (!Root.Runtime.hostConfig.devToolsAiPromptApi?.enabled) {
34
- return LanguageModelAvailability.DISABLED;
47
+ this.#availability = LanguageModelAvailability.DISABLED;
48
+ return this.#availability;
35
49
  }
36
50
  try {
37
51
  // @ts-expect-error
38
- availability = await window.LanguageModel.availability({expectedOutputs: [{type: 'text', languages: ['en']}]}) as
39
- LanguageModelAvailability;
40
- return availability;
52
+ this.#availability = await window.LanguageModel.availability(
53
+ {expectedOutputs: [{type: 'text', languages: ['en']}]}) as LanguageModelAvailability;
41
54
  } catch {
42
- return LanguageModelAvailability.UNAVAILABLE;
55
+ this.#availability = LanguageModelAvailability.UNAVAILABLE;
43
56
  }
57
+ return this.#availability;
44
58
  }
45
59
 
46
- static cachedIsAvailable(): boolean {
47
- return availability === LanguageModelAvailability.AVAILABLE &&
48
- (hasGpu || Boolean(Root.Runtime.hostConfig.devToolsAiPromptApi?.allowWithoutGpu));
49
- }
50
-
51
- static isGpuAvailable(): boolean {
52
- const hasGpuHelper = (): boolean => {
53
- const canvas = document.createElement('canvas');
54
- try {
55
- const webgl = canvas.getContext('webgl');
56
- if (!webgl) {
57
- return false;
58
- }
59
- const debugInfo = webgl.getExtension('WEBGL_debug_renderer_info');
60
- if (!debugInfo) {
61
- return false;
62
- }
63
- const renderer = webgl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
64
- if (renderer.includes('SwiftShader')) {
65
- return false;
66
- }
67
- } catch {
60
+ #isGpuAvailable(): boolean {
61
+ const canvas = document.createElement('canvas');
62
+ try {
63
+ const webgl = canvas.getContext('webgl');
64
+ if (!webgl) {
68
65
  return false;
69
66
  }
70
- return true;
71
- };
72
-
73
- if (hasGpu !== undefined) {
74
- return hasGpu;
67
+ const debugInfo = webgl.getExtension('WEBGL_debug_renderer_info');
68
+ if (!debugInfo) {
69
+ return false;
70
+ }
71
+ const renderer = webgl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
72
+ if (renderer.includes('SwiftShader')) {
73
+ return false;
74
+ }
75
+ } catch {
76
+ return false;
75
77
  }
76
- hasGpu = hasGpuHelper();
77
- return hasGpu;
78
+ return true;
78
79
  }
79
80
 
80
- private constructor(consoleInsightsSession: LanguageModel) {
81
- this.#consoleInsightsSession = consoleInsightsSession;
81
+ hasSession(): boolean {
82
+ return Boolean(this.#consoleInsightsSession);
82
83
  }
83
84
 
84
- static async instance(): Promise<BuiltInAi|undefined> {
85
- if (builtInAiInstance === undefined) {
86
- if (isFirstRun) {
87
- const languageModelAvailability = await BuiltInAi.getLanguageModelAvailability();
88
- const hasGpu = BuiltInAi.isGpuAvailable();
89
- if (hasGpu) {
90
- switch (languageModelAvailability) {
91
- case LanguageModelAvailability.UNAVAILABLE:
92
- Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.UNAVAILABLE_HAS_GPU);
93
- break;
94
- case LanguageModelAvailability.DOWNLOADABLE:
95
- Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DOWNLOADABLE_HAS_GPU);
96
- break;
97
- case LanguageModelAvailability.DOWNLOADING:
98
- Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DOWNLOADING_HAS_GPU);
99
- break;
100
- case LanguageModelAvailability.AVAILABLE:
101
- Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.AVAILABLE_HAS_GPU);
102
- break;
103
- case LanguageModelAvailability.DISABLED:
104
- Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DISABLED_HAS_GPU);
105
- break;
106
- }
107
- } else {
108
- switch (languageModelAvailability) {
109
- case LanguageModelAvailability.UNAVAILABLE:
110
- Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.UNAVAILABLE_NO_GPU);
111
- break;
112
- case LanguageModelAvailability.DOWNLOADABLE:
113
- Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DOWNLOADABLE_NO_GPU);
114
- break;
115
- case LanguageModelAvailability.DOWNLOADING:
116
- Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DOWNLOADING_NO_GPU);
117
- break;
118
- case LanguageModelAvailability.AVAILABLE:
119
- Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.AVAILABLE_NO_GPU);
120
- break;
121
- case LanguageModelAvailability.DISABLED:
122
- Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DISABLED_NO_GPU);
123
- break;
124
- }
125
- }
126
- isFirstRun = false;
127
- if (!Root.Runtime.hostConfig.devToolsAiPromptApi?.allowWithoutGpu && !hasGpu) {
128
- return undefined;
129
- }
130
- if (languageModelAvailability !== LanguageModelAvailability.AVAILABLE) {
131
- return undefined;
132
- }
133
- } else {
134
- if (!Root.Runtime.hostConfig.devToolsAiPromptApi?.allowWithoutGpu && !BuiltInAi.isGpuAvailable()) {
135
- return undefined;
136
- }
137
- if ((await BuiltInAi.getLanguageModelAvailability()) !== LanguageModelAvailability.AVAILABLE) {
138
- return undefined;
139
- }
140
- }
85
+ async initialize(): Promise<void> {
86
+ if (!Root.Runtime.hostConfig.devToolsAiPromptApi?.allowWithoutGpu && !this.#hasGpu) {
87
+ return;
88
+ }
89
+ if (this.#availability !== LanguageModelAvailability.AVAILABLE) {
90
+ return;
91
+ }
92
+ await this.#createSession();
93
+ }
94
+
95
+ async #createSession(): Promise<void> {
96
+ try {
97
+ // @ts-expect-error
98
+ this.#consoleInsightsSession = await window.LanguageModel.create({
99
+ initialPrompts: [{
100
+ role: 'system',
101
+ content: `
102
+ You are an expert web developer. Your goal is to help a human web developer who
103
+ is using Chrome DevTools to debug a web site or web app. The Chrome DevTools
104
+ console is showing a message which is either an error or a warning. Please help
105
+ the user understand the problematic console message.
141
106
 
142
- try {
143
- // @ts-expect-error
144
- const consoleInsightsSession = await window.LanguageModel.create({
145
- initialPrompts: [{
146
- role: 'system',
147
- content: `
148
- You are an expert web developer. Your goal is to help a human web developer who
149
- is using Chrome DevTools to debug a web site or web app. The Chrome DevTools
150
- console is showing a message which is either an error or a warning. Please help
151
- the user understand the problematic console message.
152
-
153
- Your instructions are as follows:
154
- - Explain the reason why the error or warning is showing up.
155
- - The explanation has a maximum length of 200 characters. Anything beyond this
156
- length will be cut off. Make sure that your explanation is at most 200 characters long.
157
- - Your explanation should not end in the middle of a sentence.
158
- - Your explanation should consist of a single paragraph only. Do not include any
159
- headings or code blocks. Only write a single paragraph of text.
160
- - Your response should be concise and to the point. Avoid lengthy explanations
161
- or unnecessary details.
162
- `
163
- }],
164
- expectedInputs: [{
165
- type: 'text',
166
- languages: ['en'],
167
- }],
168
- expectedOutputs: [{
169
- type: 'text',
170
- languages: ['en'],
171
- }],
172
- }) as LanguageModel;
173
- builtInAiInstance = new BuiltInAi(consoleInsightsSession);
174
- } catch {
175
- return undefined;
107
+ Your instructions are as follows:
108
+ - Explain the reason why the error or warning is showing up.
109
+ - The explanation has a maximum length of 200 characters. Anything beyond this
110
+ length will be cut off. Make sure that your explanation is at most 200 characters long.
111
+ - Your explanation should not end in the middle of a sentence.
112
+ - Your explanation should consist of a single paragraph only. Do not include any
113
+ headings or code blocks. Only write a single paragraph of text.
114
+ - Your response should be concise and to the point. Avoid lengthy explanations
115
+ or unnecessary details.
116
+ `
117
+ }],
118
+ expectedInputs: [{
119
+ type: 'text',
120
+ languages: ['en'],
121
+ }],
122
+ expectedOutputs: [{
123
+ type: 'text',
124
+ languages: ['en'],
125
+ }],
126
+ });
127
+ if (this.#availability !== LanguageModelAvailability.AVAILABLE) {
128
+ void this.getLanguageModelAvailability();
176
129
  }
130
+ } catch (e) {
131
+ console.error('Error when creating LanguageModel session', e.message);
177
132
  }
178
- return builtInAiInstance;
179
133
  }
180
134
 
181
135
  static removeInstance(): void {
@@ -183,6 +137,9 @@ export class BuiltInAi {
183
137
  }
184
138
 
185
139
  async * getConsoleInsight(prompt: string, abortController: AbortController): AsyncGenerator<string> {
140
+ if (!this.#consoleInsightsSession) {
141
+ return;
142
+ }
186
143
  // Clone the session to start a fresh conversation for each answer. Otherwise
187
144
  // previous dialog would pollute the context resulting in worse answers.
188
145
  let session: LanguageModel|null = null;
@@ -200,4 +157,44 @@ export class BuiltInAi {
200
157
  }
201
158
  }
202
159
  }
160
+
161
+ #sendAvailabilityMetrics(): void {
162
+ if (this.#hasGpu) {
163
+ switch (this.#availability) {
164
+ case LanguageModelAvailability.UNAVAILABLE:
165
+ Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.UNAVAILABLE_HAS_GPU);
166
+ break;
167
+ case LanguageModelAvailability.DOWNLOADABLE:
168
+ Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DOWNLOADABLE_HAS_GPU);
169
+ break;
170
+ case LanguageModelAvailability.DOWNLOADING:
171
+ Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DOWNLOADING_HAS_GPU);
172
+ break;
173
+ case LanguageModelAvailability.AVAILABLE:
174
+ Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.AVAILABLE_HAS_GPU);
175
+ break;
176
+ case LanguageModelAvailability.DISABLED:
177
+ Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DISABLED_HAS_GPU);
178
+ break;
179
+ }
180
+ } else {
181
+ switch (this.#availability) {
182
+ case LanguageModelAvailability.UNAVAILABLE:
183
+ Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.UNAVAILABLE_NO_GPU);
184
+ break;
185
+ case LanguageModelAvailability.DOWNLOADABLE:
186
+ Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DOWNLOADABLE_NO_GPU);
187
+ break;
188
+ case LanguageModelAvailability.DOWNLOADING:
189
+ Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DOWNLOADING_NO_GPU);
190
+ break;
191
+ case LanguageModelAvailability.AVAILABLE:
192
+ Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.AVAILABLE_NO_GPU);
193
+ break;
194
+ case LanguageModelAvailability.DISABLED:
195
+ Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DISABLED_NO_GPU);
196
+ break;
197
+ }
198
+ }
199
+ }
203
200
  }
@@ -35,6 +35,15 @@ export class ChangeManager {
35
35
  readonly #stylesheetChanges = new Map<Protocol.CSS.StyleSheetId, Change[]>();
36
36
  readonly #backupStylesheetChanges = new Map<Protocol.CSS.StyleSheetId, Change[]>();
37
37
 
38
+ constructor() {
39
+ SDK.TargetManager.TargetManager.instance().addModelListener(
40
+ SDK.ResourceTreeModel.ResourceTreeModel,
41
+ SDK.ResourceTreeModel.Events.PrimaryPageChanged,
42
+ this.clear,
43
+ this,
44
+ );
45
+ }
46
+
38
47
  async stashChanges(): Promise<void> {
39
48
  for (const [cssModel, stylesheetMap] of this.#cssModelToStylesheetId.entries()) {
40
49
  const stylesheetIds = Array.from(stylesheetMap.values());
@@ -17,16 +17,14 @@ import {
17
17
  type ResponseData,
18
18
  ResponseType
19
19
  } from './agents/AiAgent.js';
20
- import {FileAgent} from './agents/FileAgent.js';
21
20
  import {NetworkAgent, RequestContext} from './agents/NetworkAgent.js';
22
- import {PerformanceAgent, type PerformanceTraceContext} from './agents/PerformanceAgent.js';
21
+ import type {PerformanceTraceContext} from './agents/PerformanceAgent.js';
23
22
  import {NodeContext, StylingAgent} from './agents/StylingAgent.js';
24
23
  import {AiConversation} from './AiConversation.js';
25
24
  import {
26
25
  ConversationType,
27
26
  } from './AiHistoryStorage.js';
28
27
  import {getDisabledReasons} from './AiUtils.js';
29
- import type {ChangeManager} from './ChangeManager.js';
30
28
 
31
29
  interface ExternalStylingRequestParameters {
32
30
  conversationType: ConversationType.STYLING;
@@ -43,7 +41,6 @@ interface ExternalNetworkRequestParameters {
43
41
  export interface ExternalPerformanceAIConversationData {
44
42
  conversationHandler: ConversationHandler;
45
43
  conversation: AiConversation;
46
- agent: AiAgent<unknown>;
47
44
  selected: PerformanceTraceContext;
48
45
  }
49
46
 
@@ -122,9 +119,7 @@ export class ConversationHandler extends Common.ObjectWrapper.ObjectWrapper<Even
122
119
  aidaClient: Host.AidaClient.AidaClient, aidaAvailability?: Host.AidaClient.AidaAccessPreconditions) {
123
120
  super();
124
121
  this.#aidaClient = aidaClient;
125
- if (aidaAvailability) {
126
- this.#aidaAvailability = aidaAvailability;
127
- }
122
+ this.#aidaAvailability = aidaAvailability;
128
123
  this.#aiAssistanceEnabledSetting = this.#getAiAssistanceEnabledSetting();
129
124
  }
130
125
 
@@ -144,6 +139,10 @@ export class ConversationHandler extends Common.ObjectWrapper.ObjectWrapper<Even
144
139
  conversationHandlerInstance = undefined;
145
140
  }
146
141
 
142
+ get aidaClient(): Host.AidaClient.AidaClient {
143
+ return this.#aidaClient;
144
+ }
145
+
147
146
  #getAiAssistanceEnabledSetting(): Common.Settings.Setting<boolean>|undefined {
148
147
  try {
149
148
  return Common.Settings.moduleSetting('ai-assistance-enabled') as Common.Settings.Setting<boolean>;
@@ -207,8 +206,9 @@ export class ConversationHandler extends Common.ObjectWrapper.ObjectWrapper<Even
207
206
 
208
207
  async *
209
208
  handleConversationWithHistory(
210
- items: AsyncIterable<ResponseData, void, void>, conversation: AiConversation|undefined):
211
- AsyncGenerator<ResponseData, void, void> {
209
+ items: AsyncIterable<ResponseData, void, void>,
210
+ conversation: AiConversation|undefined,
211
+ ): AsyncGenerator<ResponseData, void, void> {
212
212
  for await (const data of items) {
213
213
  // We don't want to save partial responses to the conversation history.
214
214
  if (data.type !== ResponseType.ANSWER || data.complete) {
@@ -230,22 +230,22 @@ export class ConversationHandler extends Common.ObjectWrapper.ObjectWrapper<Even
230
230
  [],
231
231
  aiAgent.id,
232
232
  /* isReadOnly */ true,
233
+ this.#aidaClient,
234
+ undefined,
233
235
  /* isExternal */ true,
234
236
  );
235
- return yield* this.#doExternalConversation({conversation, aiAgent, prompt, selected});
237
+ return yield* this.#doExternalConversation({conversation, prompt, selected});
236
238
  }
237
239
 
238
240
  async * #doExternalConversation(opts: {
239
241
  conversation: AiConversation,
240
- aiAgent: AiAgent<unknown>,
241
242
  prompt: string,
242
243
  selected: NodeContext|PerformanceTraceContext|RequestContext|null,
243
244
  }): AsyncGenerator<ExternalRequestResponse, ExternalRequestResponse> {
244
- const {conversation, aiAgent, prompt, selected} = opts;
245
- const generator = aiAgent.run(prompt, {selected});
246
- const generatorWithHistory = this.handleConversationWithHistory(generator, conversation);
245
+ const {conversation, prompt, selected} = opts;
246
+ const generator = conversation.run(prompt, {selected});
247
247
  const devToolsLogs: object[] = [];
248
- for await (const data of generatorWithHistory) {
248
+ for await (const data of generator) {
249
249
  if (data.type !== ResponseType.ANSWER || data.complete) {
250
250
  devToolsLogs.push(data);
251
251
  }
@@ -274,7 +274,10 @@ export class ConversationHandler extends Common.ObjectWrapper.ObjectWrapper<Even
274
274
 
275
275
  async #handleExternalStylingConversation(prompt: string, selector = 'body'):
276
276
  Promise<AsyncGenerator<ExternalRequestResponse, ExternalRequestResponse>> {
277
- const stylingAgent = this.createAgent(ConversationType.STYLING);
277
+ const stylingAgent = new StylingAgent({
278
+ aidaClient: this.#aidaClient,
279
+ serverSideLoggingEnabled: isAiAssistanceServerSideLoggingEnabled(),
280
+ });
278
281
  const node = await inspectElementBySelector(selector);
279
282
  if (node) {
280
283
  await node.setAsInspectedNode();
@@ -292,7 +295,6 @@ export class ConversationHandler extends Common.ObjectWrapper.ObjectWrapper<Even
292
295
  Promise<AsyncGenerator<ExternalRequestResponse, ExternalRequestResponse>> {
293
296
  return this.#doExternalConversation({
294
297
  conversation: data.conversation,
295
- aiAgent: data.agent,
296
298
  prompt,
297
299
  selected: data.selected,
298
300
  });
@@ -300,7 +302,10 @@ export class ConversationHandler extends Common.ObjectWrapper.ObjectWrapper<Even
300
302
 
301
303
  async #handleExternalNetworkConversation(prompt: string, requestUrl: string):
302
304
  Promise<AsyncGenerator<ExternalRequestResponse, ExternalRequestResponse>> {
303
- const networkAgent = this.createAgent(ConversationType.NETWORK);
305
+ const networkAgent = new NetworkAgent({
306
+ aidaClient: this.#aidaClient,
307
+ serverSideLoggingEnabled: isAiAssistanceServerSideLoggingEnabled(),
308
+ });
304
309
  const request = await inspectNetworkRequestByUrl(requestUrl);
305
310
  if (!request) {
306
311
  return this.#generateErrorResponse(`Can't find request with the given selector ${requestUrl}`);
@@ -316,36 +321,6 @@ export class ConversationHandler extends Common.ObjectWrapper.ObjectWrapper<Even
316
321
  selected: new RequestContext(request, calculator),
317
322
  });
318
323
  }
319
-
320
- createAgent(conversationType: ConversationType, changeManager?: ChangeManager): AiAgent<unknown> {
321
- const options = {
322
- aidaClient: this.#aidaClient,
323
- serverSideLoggingEnabled: isAiAssistanceServerSideLoggingEnabled(),
324
- };
325
- let agent: AiAgent<unknown>;
326
- switch (conversationType) {
327
- case ConversationType.STYLING: {
328
- agent = new StylingAgent({
329
- ...options,
330
- changeManager,
331
- });
332
- break;
333
- }
334
- case ConversationType.NETWORK: {
335
- agent = new NetworkAgent(options);
336
- break;
337
- }
338
- case ConversationType.FILE: {
339
- agent = new FileAgent(options);
340
- break;
341
- }
342
- case ConversationType.PERFORMANCE: {
343
- agent = new PerformanceAgent(options);
344
- break;
345
- }
346
- }
347
- return agent;
348
- }
349
324
  }
350
325
 
351
326
  export const enum ConversationHandlerEvents {
@@ -486,11 +486,14 @@ export abstract class AiAgent<T> {
486
486
  }
487
487
 
488
488
  async *
489
- run(initialQuery: string, options: {
490
- selected: ConversationContext<T>|null,
491
- signal?: AbortSignal,
492
- },
493
- multimodalInput?: MultimodalInput): AsyncGenerator<ResponseData, void, void> {
489
+ run(
490
+ initialQuery: string,
491
+ options: {
492
+ selected: ConversationContext<T>|null,
493
+ signal?: AbortSignal,
494
+ },
495
+ multimodalInput?: MultimodalInput,
496
+ ): AsyncGenerator<ResponseData, void, void> {
494
497
  await options.selected?.refresh();
495
498
 
496
499
  if (options.selected) {
@@ -276,12 +276,6 @@ export class StylingAgent extends AiAgent<SDK.DOMModel.DOMNode> {
276
276
  this.#createExtensionScope = opts.createExtensionScope ?? ((changes: ChangeManager) => {
277
277
  return new ExtensionScope(changes, this.id, this.context?.getItem() ?? null);
278
278
  });
279
- SDK.TargetManager.TargetManager.instance().addModelListener(
280
- SDK.ResourceTreeModel.ResourceTreeModel,
281
- SDK.ResourceTreeModel.Events.PrimaryPageChanged,
282
- this.onPrimaryPageChanged,
283
- this,
284
- );
285
279
 
286
280
  this.declareFunction<{
287
281
  elements: string[],
@@ -418,10 +412,6 @@ const data = {
418
412
  });
419
413
  }
420
414
 
421
- onPrimaryPageChanged(): void {
422
- void this.#changes.clear();
423
- }
424
-
425
415
  async generateObservation(
426
416
  action: string,
427
417
  {
@@ -2,7 +2,8 @@
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
 
5
- import * as Common from '../../core/common/common.js';
5
+ import type * as PlatformApi from '../../core/platform/api/api.js';
6
+ import * as Platform from '../../core/platform/platform.js';
6
7
  import * as FormatterActions from '../../entrypoints/formatter_worker/FormatterActions.js'; // eslint-disable-line @devtools/es-modules-import
7
8
 
8
9
  export {DefinitionKind, ScopeKind, type ScopeTreeNode} from '../../entrypoints/formatter_worker/FormatterActions.js';
@@ -11,7 +12,7 @@ let formatterWorkerPoolInstance: FormatterWorkerPool|undefined;
11
12
 
12
13
  export class FormatterWorkerPool {
13
14
  private taskQueue: Task[];
14
- private workerTasks: Map<Common.Worker.WorkerWrapper, Task|null>;
15
+ private workerTasks: Map<PlatformApi.HostRuntime.Worker, Task|null>;
15
16
 
16
17
  constructor() {
17
18
  this.taskQueue = [];
@@ -42,9 +43,9 @@ export class FormatterWorkerPool {
42
43
  formatterWorkerPoolInstance = undefined;
43
44
  }
44
45
 
45
- private createWorker(): Common.Worker.WorkerWrapper {
46
- const worker = Common.Worker.WorkerWrapper.fromURL(
47
- new URL('../../entrypoints/formatter_worker/formatter_worker-entrypoint.js', import.meta.url));
46
+ private createWorker(): PlatformApi.HostRuntime.Worker {
47
+ const worker = Platform.HostRuntime.HOST_RUNTIME.createWorker(
48
+ new URL('../../entrypoints/formatter_worker/formatter_worker-entrypoint.js', import.meta.url).toString());
48
49
  worker.onmessage = this.onWorkerMessage.bind(this, worker);
49
50
  worker.onerror = this.onWorkerError.bind(this, worker);
50
51
  return worker;
@@ -72,7 +73,8 @@ export class FormatterWorkerPool {
72
73
  }
73
74
  }
74
75
 
75
- private onWorkerMessage(worker: Common.Worker.WorkerWrapper, event: MessageEvent): void {
76
+ private onWorkerMessage(worker: PlatformApi.HostRuntime.Worker, event: PlatformApi.HostRuntime.WorkerMessageEvent):
77
+ void {
76
78
  const task = this.workerTasks.get(worker);
77
79
  if (!task) {
78
80
  return;
@@ -87,7 +89,7 @@ export class FormatterWorkerPool {
87
89
  task.callback(event.data ? event.data : null);
88
90
  }
89
91
 
90
- private onWorkerError(worker: Common.Worker.WorkerWrapper, event: Event): void {
92
+ private onWorkerError(worker: PlatformApi.HostRuntime.Worker, event: Event): void {
91
93
  console.error(event);
92
94
  const task = this.workerTasks.get(worker);
93
95
  worker.terminate();
@@ -248,7 +248,7 @@ export class Importer {
248
248
  }
249
249
  }
250
250
 
251
- if (pageLoad && pageLoad.mainRequest === request) {
251
+ if (pageLoad?.mainRequest === request) {
252
252
  return Common.ResourceType.resourceTypes.Document;
253
253
  }
254
254
 
@@ -71,7 +71,7 @@ export class ContrastCheckTrigger {
71
71
  // Otherwise, it should be triggered when the page load event fires.
72
72
  const response = await frame.resourceTreeModel().target().runtimeAgent().invoke_evaluate(
73
73
  {expression: 'document.readyState', returnByValue: true});
74
- if (response.result && response.result.value === 'complete') {
74
+ if (response.result?.value === 'complete') {
75
75
  this.#checkContrast(frame.resourceTreeModel());
76
76
  }
77
77
  }
@@ -155,7 +155,7 @@ export class AutomaticFileSystemManager extends Common.ObjectWrapper.ObjectWrapp
155
155
  let automaticFileSystem = this.#automaticFileSystem;
156
156
  if (projectSettings.workspace) {
157
157
  const {root, uuid} = projectSettings.workspace;
158
- if (automaticFileSystem === null || automaticFileSystem.root !== root || automaticFileSystem.uuid !== uuid) {
158
+ if (automaticFileSystem?.root !== root || automaticFileSystem.uuid !== uuid) {
159
159
  automaticFileSystem = Object.freeze({root, uuid, state: 'disconnected'});
160
160
  }
161
161
  } else if (automaticFileSystem !== null) {
@@ -327,7 +327,7 @@ export class AXNodePropertyTreeElement extends UI.TreeOutline.TreeElement {
327
327
  }
328
328
 
329
329
  appendRelatedNodeListValueElement(value: Protocol.Accessibility.AXValue): void {
330
- if (value.relatedNodes && value.relatedNodes.length === 1 && !value.value) {
330
+ if (value.relatedNodes?.length === 1 && !value.value) {
331
331
  this.appendRelatedNodeInline(value.relatedNodes[0]);
332
332
  return;
333
333
  }