devtools-tracing 1.0.0

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 (397) hide show
  1. package/generate.ts +643 -0
  2. package/index.ts +16 -0
  3. package/lib/front_end/core/common/App.ts +7 -0
  4. package/lib/front_end/core/common/AppProvider.ts +32 -0
  5. package/lib/front_end/core/common/Base64.ts +47 -0
  6. package/lib/front_end/core/common/CharacterIdMap.ts +30 -0
  7. package/lib/front_end/core/common/Color.ts +2506 -0
  8. package/lib/front_end/core/common/ColorConverter.ts +402 -0
  9. package/lib/front_end/core/common/ColorUtils.ts +252 -0
  10. package/lib/front_end/core/common/Console.ts +114 -0
  11. package/lib/front_end/core/common/Debouncer.ts +15 -0
  12. package/lib/front_end/core/common/EventTarget.ts +52 -0
  13. package/lib/front_end/core/common/Gzip.ts +74 -0
  14. package/lib/front_end/core/common/JavaScriptMetaData.ts +29 -0
  15. package/lib/front_end/core/common/Lazy.ts +31 -0
  16. package/lib/front_end/core/common/Linkifier.ts +55 -0
  17. package/lib/front_end/core/common/MapWithDefault.ts +26 -0
  18. package/lib/front_end/core/common/Mutex.ts +55 -0
  19. package/lib/front_end/core/common/Object.ts +145 -0
  20. package/lib/front_end/core/common/ParsedURL.ts +554 -0
  21. package/lib/front_end/core/common/Progress.ts +180 -0
  22. package/lib/front_end/core/common/QueryParamHandler.ts +7 -0
  23. package/lib/front_end/core/common/ResolverBase.ts +85 -0
  24. package/lib/front_end/core/common/ResourceType.ts +588 -0
  25. package/lib/front_end/core/common/ReturnToPanel.ts +17 -0
  26. package/lib/front_end/core/common/Revealer.ts +192 -0
  27. package/lib/front_end/core/common/Runnable.ts +41 -0
  28. package/lib/front_end/core/common/SegmentedRange.ts +87 -0
  29. package/lib/front_end/core/common/SettingRegistration.ts +339 -0
  30. package/lib/front_end/core/common/Settings.ts +1497 -0
  31. package/lib/front_end/core/common/SimpleHistoryManager.ts +124 -0
  32. package/lib/front_end/core/common/StringOutputStream.ts +26 -0
  33. package/lib/front_end/core/common/TextDictionary.ts +48 -0
  34. package/lib/front_end/core/common/Throttler.ts +99 -0
  35. package/lib/front_end/core/common/Trie.ts +152 -0
  36. package/lib/front_end/core/common/Worker.ts +60 -0
  37. package/lib/front_end/core/common/common.ts +81 -0
  38. package/lib/front_end/core/host/AidaClient.ts +733 -0
  39. package/lib/front_end/core/host/GdpClient.ts +316 -0
  40. package/lib/front_end/core/host/InspectorFrontendHost.ts +648 -0
  41. package/lib/front_end/core/host/InspectorFrontendHostAPI.ts +551 -0
  42. package/lib/front_end/core/host/Platform.ts +76 -0
  43. package/lib/front_end/core/host/ResourceLoader.ts +282 -0
  44. package/lib/front_end/core/host/UserMetrics.ts +1230 -0
  45. package/lib/front_end/core/host/host.ts +23 -0
  46. package/lib/front_end/core/i18n/ByteUtilities.ts +82 -0
  47. package/lib/front_end/core/i18n/DevToolsLocale.ts +87 -0
  48. package/lib/front_end/core/i18n/NumberFormatter.ts +82 -0
  49. package/lib/front_end/core/i18n/i18n.ts +17 -0
  50. package/lib/front_end/core/i18n/i18nImpl.ts +204 -0
  51. package/lib/front_end/core/i18n/i18nTypes.ts +10 -0
  52. package/lib/front_end/core/i18n/locales.js +14 -0
  53. package/lib/front_end/core/i18n/time-utilities.ts +174 -0
  54. package/lib/front_end/core/platform/ArrayUtilities.ts +271 -0
  55. package/lib/front_end/core/platform/Brand.ts +23 -0
  56. package/lib/front_end/core/platform/Constructor.ts +10 -0
  57. package/lib/front_end/core/platform/DOMUtilities.ts +138 -0
  58. package/lib/front_end/core/platform/DateUtilities.ts +15 -0
  59. package/lib/front_end/core/platform/DevToolsPath.ts +53 -0
  60. package/lib/front_end/core/platform/KeyboardUtilities.ts +38 -0
  61. package/lib/front_end/core/platform/MapUtilities.ts +95 -0
  62. package/lib/front_end/core/platform/MimeType.ts +175 -0
  63. package/lib/front_end/core/platform/NumberUtilities.ts +80 -0
  64. package/lib/front_end/core/platform/StringUtilities.ts +588 -0
  65. package/lib/front_end/core/platform/Timing.ts +17 -0
  66. package/lib/front_end/core/platform/TypedArrayUtilities.ts +189 -0
  67. package/lib/front_end/core/platform/TypescriptUtilities.ts +86 -0
  68. package/lib/front_end/core/platform/UIString.ts +39 -0
  69. package/lib/front_end/core/platform/UserVisibleError.ts +28 -0
  70. package/lib/front_end/core/platform/platform.ts +45 -0
  71. package/lib/front_end/core/protocol_client/ConnectionTransport.ts +26 -0
  72. package/lib/front_end/core/protocol_client/InspectorBackend.ts +1050 -0
  73. package/lib/front_end/core/protocol_client/NodeURL.ts +42 -0
  74. package/lib/front_end/core/protocol_client/protocol_client.ts +13 -0
  75. package/lib/front_end/core/root/Runtime.ts +609 -0
  76. package/lib/front_end/core/root/root.ts +6 -0
  77. package/lib/front_end/core/sdk/AccessibilityModel.ts +353 -0
  78. package/lib/front_end/core/sdk/AnimationModel.ts +1041 -0
  79. package/lib/front_end/core/sdk/AutofillModel.ts +184 -0
  80. package/lib/front_end/core/sdk/CPUProfilerModel.ts +148 -0
  81. package/lib/front_end/core/sdk/CPUThrottlingManager.ts +282 -0
  82. package/lib/front_end/core/sdk/CSSContainerQuery.ts +139 -0
  83. package/lib/front_end/core/sdk/CSSFontFace.ts +40 -0
  84. package/lib/front_end/core/sdk/CSSLayer.ts +30 -0
  85. package/lib/front_end/core/sdk/CSSMatchedStyles.ts +1646 -0
  86. package/lib/front_end/core/sdk/CSSMedia.ts +121 -0
  87. package/lib/front_end/core/sdk/CSSMetadata.ts +1647 -0
  88. package/lib/front_end/core/sdk/CSSModel.ts +1128 -0
  89. package/lib/front_end/core/sdk/CSSProperty.ts +384 -0
  90. package/lib/front_end/core/sdk/CSSPropertyParser.ts +681 -0
  91. package/lib/front_end/core/sdk/CSSPropertyParserMatchers.ts +1395 -0
  92. package/lib/front_end/core/sdk/CSSQuery.ts +72 -0
  93. package/lib/front_end/core/sdk/CSSRule.ts +465 -0
  94. package/lib/front_end/core/sdk/CSSScope.ts +30 -0
  95. package/lib/front_end/core/sdk/CSSStartingStyle.ts +29 -0
  96. package/lib/front_end/core/sdk/CSSStyleDeclaration.ts +313 -0
  97. package/lib/front_end/core/sdk/CSSStyleSheetHeader.ts +196 -0
  98. package/lib/front_end/core/sdk/CSSSupports.ts +33 -0
  99. package/lib/front_end/core/sdk/CategorizedBreakpoint.ts +64 -0
  100. package/lib/front_end/core/sdk/ChildTargetManager.ts +314 -0
  101. package/lib/front_end/core/sdk/CompilerSourceMappingContentProvider.ts +62 -0
  102. package/lib/front_end/core/sdk/Connections.ts +293 -0
  103. package/lib/front_end/core/sdk/ConsoleModel.ts +808 -0
  104. package/lib/front_end/core/sdk/ConsoleModelTypes.ts +15 -0
  105. package/lib/front_end/core/sdk/Cookie.ts +319 -0
  106. package/lib/front_end/core/sdk/CookieModel.ts +239 -0
  107. package/lib/front_end/core/sdk/CookieParser.ts +185 -0
  108. package/lib/front_end/core/sdk/DOMDebuggerModel.ts +787 -0
  109. package/lib/front_end/core/sdk/DOMModel.ts +1961 -0
  110. package/lib/front_end/core/sdk/DebuggerModel.ts +1605 -0
  111. package/lib/front_end/core/sdk/EmulationModel.ts +648 -0
  112. package/lib/front_end/core/sdk/EnhancedTracesParser.ts +515 -0
  113. package/lib/front_end/core/sdk/EventBreakpointsModel.ts +183 -0
  114. package/lib/front_end/core/sdk/FrameAssociated.ts +11 -0
  115. package/lib/front_end/core/sdk/FrameManager.ts +259 -0
  116. package/lib/front_end/core/sdk/HeapProfilerModel.ts +225 -0
  117. package/lib/front_end/core/sdk/HttpReasonPhraseStrings.ts +77 -0
  118. package/lib/front_end/core/sdk/IOModel.ts +91 -0
  119. package/lib/front_end/core/sdk/IsolateManager.ts +257 -0
  120. package/lib/front_end/core/sdk/IssuesModel.ts +70 -0
  121. package/lib/front_end/core/sdk/LayerTreeBase.ts +169 -0
  122. package/lib/front_end/core/sdk/LogModel.ts +56 -0
  123. package/lib/front_end/core/sdk/NetworkManager.ts +2823 -0
  124. package/lib/front_end/core/sdk/NetworkRequest.ts +2253 -0
  125. package/lib/front_end/core/sdk/OverlayColorGenerator.ts +52 -0
  126. package/lib/front_end/core/sdk/OverlayModel.ts +1011 -0
  127. package/lib/front_end/core/sdk/OverlayPersistentHighlighter.ts +522 -0
  128. package/lib/front_end/core/sdk/PageLoad.ts +35 -0
  129. package/lib/front_end/core/sdk/PageResourceLoader.ts +435 -0
  130. package/lib/front_end/core/sdk/PaintProfiler.ts +110 -0
  131. package/lib/front_end/core/sdk/PerformanceMetricsModel.ts +84 -0
  132. package/lib/front_end/core/sdk/PreloadingModel.ts +863 -0
  133. package/lib/front_end/core/sdk/RehydratingConnection.ts +386 -0
  134. package/lib/front_end/core/sdk/RehydratingObject.ts +66 -0
  135. package/lib/front_end/core/sdk/RemoteObject.ts +1160 -0
  136. package/lib/front_end/core/sdk/Resource.ts +232 -0
  137. package/lib/front_end/core/sdk/ResourceTreeModel.ts +1160 -0
  138. package/lib/front_end/core/sdk/RuntimeModel.ts +732 -0
  139. package/lib/front_end/core/sdk/SDKModel.ts +65 -0
  140. package/lib/front_end/core/sdk/ScopeTreeCache.ts +45 -0
  141. package/lib/front_end/core/sdk/ScreenCaptureModel.ts +255 -0
  142. package/lib/front_end/core/sdk/Script.ts +534 -0
  143. package/lib/front_end/core/sdk/SecurityOriginManager.ts +76 -0
  144. package/lib/front_end/core/sdk/ServerSentEvents.ts +80 -0
  145. package/lib/front_end/core/sdk/ServerSentEventsProtocol.ts +122 -0
  146. package/lib/front_end/core/sdk/ServerTiming.ts +260 -0
  147. package/lib/front_end/core/sdk/ServiceWorkerCacheModel.ts +377 -0
  148. package/lib/front_end/core/sdk/ServiceWorkerManager.ts +605 -0
  149. package/lib/front_end/core/sdk/SourceMap.ts +867 -0
  150. package/lib/front_end/core/sdk/SourceMapCache.ts +54 -0
  151. package/lib/front_end/core/sdk/SourceMapFunctionRanges.ts +156 -0
  152. package/lib/front_end/core/sdk/SourceMapManager.ts +239 -0
  153. package/lib/front_end/core/sdk/SourceMapScopeChainEntry.ts +189 -0
  154. package/lib/front_end/core/sdk/SourceMapScopesInfo.ts +508 -0
  155. package/lib/front_end/core/sdk/StorageBucketsModel.ts +204 -0
  156. package/lib/front_end/core/sdk/StorageKeyManager.ts +98 -0
  157. package/lib/front_end/core/sdk/Target.ts +332 -0
  158. package/lib/front_end/core/sdk/TargetManager.ts +453 -0
  159. package/lib/front_end/core/sdk/TraceObject.ts +61 -0
  160. package/lib/front_end/core/sdk/WebAuthnModel.ts +104 -0
  161. package/lib/front_end/core/sdk/sdk.ts +174 -0
  162. package/lib/front_end/entrypoints/formatter_worker/FormatterActions.ts +59 -0
  163. package/lib/front_end/generated/InspectorBackendCommands.js +1617 -0
  164. package/lib/front_end/generated/SupportedCSSProperties.js +7512 -0
  165. package/lib/front_end/generated/protocol-proxy-api.d.ts +5022 -0
  166. package/lib/front_end/generated/protocol.ts +22014 -0
  167. package/lib/front_end/models/cpu_profile/CPUProfileDataModel.ts +571 -0
  168. package/lib/front_end/models/cpu_profile/ProfileTreeModel.ts +103 -0
  169. package/lib/front_end/models/cpu_profile/cpu_profile.ts +11 -0
  170. package/lib/front_end/models/formatter/FormatterWorkerPool.ts +219 -0
  171. package/lib/front_end/models/formatter/ScriptFormatter.ts +112 -0
  172. package/lib/front_end/models/formatter/formatter.ts +8 -0
  173. package/lib/front_end/models/text_utils/CodeMirrorUtils.ts +37 -0
  174. package/lib/front_end/models/text_utils/ContentData.ts +199 -0
  175. package/lib/front_end/models/text_utils/ContentProvider.ts +68 -0
  176. package/lib/front_end/models/text_utils/StaticContentProvider.ts +49 -0
  177. package/lib/front_end/models/text_utils/StreamingContentData.ts +108 -0
  178. package/lib/front_end/models/text_utils/Text.ts +90 -0
  179. package/lib/front_end/models/text_utils/TextCursor.ts +44 -0
  180. package/lib/front_end/models/text_utils/TextRange.ts +266 -0
  181. package/lib/front_end/models/text_utils/TextUtils.ts +401 -0
  182. package/lib/front_end/models/text_utils/WasmDisassembly.ts +87 -0
  183. package/lib/front_end/models/text_utils/text_utils.ts +27 -0
  184. package/lib/front_end/models/trace/EntityMapper.ts +141 -0
  185. package/lib/front_end/models/trace/EventsSerializer.ts +101 -0
  186. package/lib/front_end/models/trace/LanternComputationData.ts +438 -0
  187. package/lib/front_end/models/trace/ModelImpl.ts +236 -0
  188. package/lib/front_end/models/trace/Name.ts +136 -0
  189. package/lib/front_end/models/trace/Processor.ts +652 -0
  190. package/lib/front_end/models/trace/Styles.ts +1138 -0
  191. package/lib/front_end/models/trace/extras/FilmStrip.ts +78 -0
  192. package/lib/front_end/models/trace/extras/MainThreadActivity.ts +86 -0
  193. package/lib/front_end/models/trace/extras/ScriptDuplication.ts +236 -0
  194. package/lib/front_end/models/trace/extras/StackTraceForEvent.ts +203 -0
  195. package/lib/front_end/models/trace/extras/ThirdParties.ts +164 -0
  196. package/lib/front_end/models/trace/extras/TraceFilter.ts +62 -0
  197. package/lib/front_end/models/trace/extras/TraceTree.ts +701 -0
  198. package/lib/front_end/models/trace/extras/extras.ts +11 -0
  199. package/lib/front_end/models/trace/handlers/AnimationFramesHandler.ts +128 -0
  200. package/lib/front_end/models/trace/handlers/AnimationHandler.ts +36 -0
  201. package/lib/front_end/models/trace/handlers/AsyncJSCallsHandler.ts +239 -0
  202. package/lib/front_end/models/trace/handlers/AuctionWorkletsHandler.ts +183 -0
  203. package/lib/front_end/models/trace/handlers/DOMStatsHandler.ts +31 -0
  204. package/lib/front_end/models/trace/handlers/ExtensionTraceDataHandler.ts +306 -0
  205. package/lib/front_end/models/trace/handlers/FlowsHandler.ts +175 -0
  206. package/lib/front_end/models/trace/handlers/FramesHandler.ts +571 -0
  207. package/lib/front_end/models/trace/handlers/GPUHandler.ts +50 -0
  208. package/lib/front_end/models/trace/handlers/ImagePaintingHandler.ts +183 -0
  209. package/lib/front_end/models/trace/handlers/InitiatorsHandler.ts +193 -0
  210. package/lib/front_end/models/trace/handlers/InvalidationsHandler.ts +168 -0
  211. package/lib/front_end/models/trace/handlers/LargestImagePaintHandler.ts +109 -0
  212. package/lib/front_end/models/trace/handlers/LargestTextPaintHandler.ts +35 -0
  213. package/lib/front_end/models/trace/handlers/LayerTreeHandler.ts +123 -0
  214. package/lib/front_end/models/trace/handlers/LayoutShiftsHandler.ts +573 -0
  215. package/lib/front_end/models/trace/handlers/MemoryHandler.ts +31 -0
  216. package/lib/front_end/models/trace/handlers/MetaHandler.ts +525 -0
  217. package/lib/front_end/models/trace/handlers/ModelHandlers.ts +34 -0
  218. package/lib/front_end/models/trace/handlers/NetworkRequestsHandler.ts +672 -0
  219. package/lib/front_end/models/trace/handlers/PageFramesHandler.ts +52 -0
  220. package/lib/front_end/models/trace/handlers/PageLoadMetricsHandler.ts +460 -0
  221. package/lib/front_end/models/trace/handlers/RendererHandler.ts +428 -0
  222. package/lib/front_end/models/trace/handlers/SamplesHandler.ts +271 -0
  223. package/lib/front_end/models/trace/handlers/ScreenshotsHandler.ts +122 -0
  224. package/lib/front_end/models/trace/handlers/ScriptsHandler.ts +336 -0
  225. package/lib/front_end/models/trace/handlers/SelectorStatsHandler.ts +110 -0
  226. package/lib/front_end/models/trace/handlers/Threads.ts +139 -0
  227. package/lib/front_end/models/trace/handlers/UserInteractionsHandler.ts +400 -0
  228. package/lib/front_end/models/trace/handlers/UserTimingsHandler.ts +233 -0
  229. package/lib/front_end/models/trace/handlers/WarningsHandler.ts +162 -0
  230. package/lib/front_end/models/trace/handlers/WorkersHandler.ts +45 -0
  231. package/lib/front_end/models/trace/handlers/handlers.ts +8 -0
  232. package/lib/front_end/models/trace/handlers/helpers.ts +196 -0
  233. package/lib/front_end/models/trace/handlers/types.ts +75 -0
  234. package/lib/front_end/models/trace/helpers/Extensions.ts +54 -0
  235. package/lib/front_end/models/trace/helpers/Network.ts +129 -0
  236. package/lib/front_end/models/trace/helpers/SamplesIntegrator.ts +544 -0
  237. package/lib/front_end/models/trace/helpers/SyntheticEvents.ts +87 -0
  238. package/lib/front_end/models/trace/helpers/Timing.ts +248 -0
  239. package/lib/front_end/models/trace/helpers/Trace.ts +928 -0
  240. package/lib/front_end/models/trace/helpers/TreeHelpers.ts +320 -0
  241. package/lib/front_end/models/trace/helpers/helpers.ts +11 -0
  242. package/lib/front_end/models/trace/insights/CLSCulprits.ts +668 -0
  243. package/lib/front_end/models/trace/insights/Cache.ts +269 -0
  244. package/lib/front_end/models/trace/insights/Common.ts +453 -0
  245. package/lib/front_end/models/trace/insights/DOMSize.ts +223 -0
  246. package/lib/front_end/models/trace/insights/DocumentLatency.ts +319 -0
  247. package/lib/front_end/models/trace/insights/DuplicatedJavaScript.ts +126 -0
  248. package/lib/front_end/models/trace/insights/FontDisplay.ts +119 -0
  249. package/lib/front_end/models/trace/insights/ForcedReflow.ts +220 -0
  250. package/lib/front_end/models/trace/insights/INPBreakdown.ts +171 -0
  251. package/lib/front_end/models/trace/insights/ImageDelivery.ts +348 -0
  252. package/lib/front_end/models/trace/insights/LCPBreakdown.ts +268 -0
  253. package/lib/front_end/models/trace/insights/LCPDiscovery.ts +237 -0
  254. package/lib/front_end/models/trace/insights/LegacyJavaScript.ts +138 -0
  255. package/lib/front_end/models/trace/insights/Models.ts +22 -0
  256. package/lib/front_end/models/trace/insights/ModernHTTP.ts +257 -0
  257. package/lib/front_end/models/trace/insights/NetworkDependencyTree.ts +726 -0
  258. package/lib/front_end/models/trace/insights/RenderBlocking.ts +257 -0
  259. package/lib/front_end/models/trace/insights/SlowCSSSelector.ts +175 -0
  260. package/lib/front_end/models/trace/insights/Statistics.ts +101 -0
  261. package/lib/front_end/models/trace/insights/ThirdParties.ts +130 -0
  262. package/lib/front_end/models/trace/insights/Viewport.ts +138 -0
  263. package/lib/front_end/models/trace/insights/insights.ts +10 -0
  264. package/lib/front_end/models/trace/insights/types.ts +157 -0
  265. package/lib/front_end/models/trace/lantern/core/LanternError.ts +7 -0
  266. package/lib/front_end/models/trace/lantern/core/NetworkAnalyzer.ts +619 -0
  267. package/lib/front_end/models/trace/lantern/core/core.ts +6 -0
  268. package/lib/front_end/models/trace/lantern/graph/BaseNode.ts +345 -0
  269. package/lib/front_end/models/trace/lantern/graph/CPUNode.ts +80 -0
  270. package/lib/front_end/models/trace/lantern/graph/NetworkNode.ts +101 -0
  271. package/lib/front_end/models/trace/lantern/graph/PageDependencyGraph.ts +636 -0
  272. package/lib/front_end/models/trace/lantern/graph/graph.ts +8 -0
  273. package/lib/front_end/models/trace/lantern/lantern.ts +17 -0
  274. package/lib/front_end/models/trace/lantern/metrics/FirstContentfulPaint.ts +187 -0
  275. package/lib/front_end/models/trace/lantern/metrics/Interactive.ts +88 -0
  276. package/lib/front_end/models/trace/lantern/metrics/LargestContentfulPaint.ts +92 -0
  277. package/lib/front_end/models/trace/lantern/metrics/MaxPotentialFID.ts +72 -0
  278. package/lib/front_end/models/trace/lantern/metrics/Metric.ts +126 -0
  279. package/lib/front_end/models/trace/lantern/metrics/SpeedIndex.ts +126 -0
  280. package/lib/front_end/models/trace/lantern/metrics/TBTUtils.ts +82 -0
  281. package/lib/front_end/models/trace/lantern/metrics/TotalBlockingTime.ts +112 -0
  282. package/lib/front_end/models/trace/lantern/metrics/metrics.ts +12 -0
  283. package/lib/front_end/models/trace/lantern/simulation/ConnectionPool.ts +150 -0
  284. package/lib/front_end/models/trace/lantern/simulation/Constants.ts +46 -0
  285. package/lib/front_end/models/trace/lantern/simulation/DNSCache.ts +61 -0
  286. package/lib/front_end/models/trace/lantern/simulation/SimulationTimingMap.ts +196 -0
  287. package/lib/front_end/models/trace/lantern/simulation/Simulator.ts +556 -0
  288. package/lib/front_end/models/trace/lantern/simulation/TCPConnection.ts +192 -0
  289. package/lib/front_end/models/trace/lantern/simulation/simulation.ts +10 -0
  290. package/lib/front_end/models/trace/lantern/types/Lantern.ts +220 -0
  291. package/lib/front_end/models/trace/lantern/types/types.ts +5 -0
  292. package/lib/front_end/models/trace/trace.ts +33 -0
  293. package/lib/front_end/models/trace/types/Configuration.ts +110 -0
  294. package/lib/front_end/models/trace/types/Extensions.ts +136 -0
  295. package/lib/front_end/models/trace/types/File.ts +281 -0
  296. package/lib/front_end/models/trace/types/Overlays.ts +138 -0
  297. package/lib/front_end/models/trace/types/Timing.ts +30 -0
  298. package/lib/front_end/models/trace/types/TraceEvents.ts +3277 -0
  299. package/lib/front_end/models/trace/types/types.ts +10 -0
  300. package/lib/front_end/third_party/i18n/LICENSE +202 -0
  301. package/lib/front_end/third_party/i18n/README.chromium +15 -0
  302. package/lib/front_end/third_party/i18n/i18n-impl.ts +61 -0
  303. package/lib/front_end/third_party/i18n/i18n.ts +11 -0
  304. package/lib/front_end/third_party/i18n/localized-string-set.ts +129 -0
  305. package/lib/front_end/third_party/intl-messageformat/LICENSE +33 -0
  306. package/lib/front_end/third_party/intl-messageformat/README.chromium +24 -0
  307. package/lib/front_end/third_party/intl-messageformat/intl-messageformat-tsconfig.json +16 -0
  308. package/lib/front_end/third_party/intl-messageformat/intl-messageformat.ts +6 -0
  309. package/lib/front_end/third_party/intl-messageformat/package/LICENSE.md +33 -0
  310. package/lib/front_end/third_party/intl-messageformat/package/README.md +3 -0
  311. package/lib/front_end/third_party/intl-messageformat/package/index.d.ts +6 -0
  312. package/lib/front_end/third_party/intl-messageformat/package/index.d.ts.map +1 -0
  313. package/lib/front_end/third_party/intl-messageformat/package/index.js +13 -0
  314. package/lib/front_end/third_party/intl-messageformat/package/intl-messageformat.esm.d.ts +5 -0
  315. package/lib/front_end/third_party/intl-messageformat/package/intl-messageformat.esm.js +1710 -0
  316. package/lib/front_end/third_party/intl-messageformat/package/intl-messageformat.iife.js +1815 -0
  317. package/lib/front_end/third_party/intl-messageformat/package/lib/index.d.ts +6 -0
  318. package/lib/front_end/third_party/intl-messageformat/package/lib/index.d.ts.map +1 -0
  319. package/lib/front_end/third_party/intl-messageformat/package/lib/index.js +10 -0
  320. package/lib/front_end/third_party/intl-messageformat/package/lib/src/core.d.ts +34 -0
  321. package/lib/front_end/third_party/intl-messageformat/package/lib/src/core.d.ts.map +1 -0
  322. package/lib/front_end/third_party/intl-messageformat/package/lib/src/core.js +229 -0
  323. package/lib/front_end/third_party/intl-messageformat/package/lib/src/error.d.ts +28 -0
  324. package/lib/front_end/third_party/intl-messageformat/package/lib/src/error.d.ts.map +1 -0
  325. package/lib/front_end/third_party/intl-messageformat/package/lib/src/error.js +48 -0
  326. package/lib/front_end/third_party/intl-messageformat/package/lib/src/formatters.d.ts +34 -0
  327. package/lib/front_end/third_party/intl-messageformat/package/lib/src/formatters.d.ts.map +1 -0
  328. package/lib/front_end/third_party/intl-messageformat/package/lib/src/formatters.js +179 -0
  329. package/lib/front_end/third_party/intl-messageformat/package/package.json +42 -0
  330. package/lib/front_end/third_party/intl-messageformat/package/src/core.d.ts +34 -0
  331. package/lib/front_end/third_party/intl-messageformat/package/src/core.d.ts.map +1 -0
  332. package/lib/front_end/third_party/intl-messageformat/package/src/core.js +230 -0
  333. package/lib/front_end/third_party/intl-messageformat/package/src/error.d.ts +28 -0
  334. package/lib/front_end/third_party/intl-messageformat/package/src/error.d.ts.map +1 -0
  335. package/lib/front_end/third_party/intl-messageformat/package/src/error.js +51 -0
  336. package/lib/front_end/third_party/intl-messageformat/package/src/formatters.d.ts +34 -0
  337. package/lib/front_end/third_party/intl-messageformat/package/src/formatters.d.ts.map +1 -0
  338. package/lib/front_end/third_party/intl-messageformat/package/src/formatters.js +182 -0
  339. package/lib/front_end/third_party/intl-messageformat/package/src/icu-messageformat-parser/error.d.ts +79 -0
  340. package/lib/front_end/third_party/intl-messageformat/package/src/icu-messageformat-parser/index.d.ts +15 -0
  341. package/lib/front_end/third_party/intl-messageformat/package/src/icu-messageformat-parser/parser.d.ts +153 -0
  342. package/lib/front_end/third_party/intl-messageformat/package/src/icu-messageformat-parser/types.d.ts +139 -0
  343. package/lib/front_end/third_party/legacy-javascript/LICENSE +202 -0
  344. package/lib/front_end/third_party/legacy-javascript/README.chromium +13 -0
  345. package/lib/front_end/third_party/legacy-javascript/legacy-javascript-tsconfig.json +8 -0
  346. package/lib/front_end/third_party/legacy-javascript/legacy-javascript.ts +3 -0
  347. package/lib/front_end/third_party/legacy-javascript/lib/legacy-javascript.d.ts +18 -0
  348. package/lib/front_end/third_party/legacy-javascript/lib/legacy-javascript.js +943 -0
  349. package/lib/front_end/third_party/legacy-javascript/package.json +8 -0
  350. package/lib/front_end/third_party/legacy-javascript/rebuild.sh +9 -0
  351. package/lib/front_end/third_party/third-party-web/LICENSE +20 -0
  352. package/lib/front_end/third_party/third-party-web/README.chromium +13 -0
  353. package/lib/front_end/third_party/third-party-web/lib/nostats-subset.d.ts +2 -0
  354. package/lib/front_end/third_party/third-party-web/lib/nostats-subset.js +149 -0
  355. package/lib/front_end/third_party/third-party-web/package/LICENSE +20 -0
  356. package/lib/front_end/third_party/third-party-web/package/README.md +929 -0
  357. package/lib/front_end/third_party/third-party-web/package/dist/entities-httparchive-nostats.json +1 -0
  358. package/lib/front_end/third_party/third-party-web/package/dist/entities-httparchive.json +1 -0
  359. package/lib/front_end/third_party/third-party-web/package/dist/entities-nostats.json +1 -0
  360. package/lib/front_end/third_party/third-party-web/package/dist/entities.json +1 -0
  361. package/lib/front_end/third_party/third-party-web/package/facades.md +46 -0
  362. package/lib/front_end/third_party/third-party-web/package/httparchive-nostats-subset.d.ts +1 -0
  363. package/lib/front_end/third_party/third-party-web/package/httparchive-nostats-subset.js +1 -0
  364. package/lib/front_end/third_party/third-party-web/package/httparchive-subset.d.ts +1 -0
  365. package/lib/front_end/third_party/third-party-web/package/httparchive-subset.js +1 -0
  366. package/lib/front_end/third_party/third-party-web/package/lib/__snapshots__/index.test.js.snap +1006 -0
  367. package/lib/front_end/third_party/third-party-web/package/lib/create-entity-finder-api.js +139 -0
  368. package/lib/front_end/third_party/third-party-web/package/lib/create-entity-finder-api.test.js +44 -0
  369. package/lib/front_end/third_party/third-party-web/package/lib/entities.test.js +27 -0
  370. package/lib/front_end/third_party/third-party-web/package/lib/index.d.ts +34 -0
  371. package/lib/front_end/third_party/third-party-web/package/lib/index.js +3 -0
  372. package/lib/front_end/third_party/third-party-web/package/lib/index.test.js +246 -0
  373. package/lib/front_end/third_party/third-party-web/package/lib/markdown/faqs.partial.md +36 -0
  374. package/lib/front_end/third_party/third-party-web/package/lib/markdown/goals.partial.md +9 -0
  375. package/lib/front_end/third_party/third-party-web/package/lib/markdown/methodology.partial.md +5 -0
  376. package/lib/front_end/third_party/third-party-web/package/lib/markdown/template.md +151 -0
  377. package/lib/front_end/third_party/third-party-web/package/lib/markdown/updates/2019-02-01.md +1 -0
  378. package/lib/front_end/third_party/third-party-web/package/lib/markdown/updates/2019-03-01.md +1 -0
  379. package/lib/front_end/third_party/third-party-web/package/lib/markdown/updates/2019-05-06.md +1 -0
  380. package/lib/front_end/third_party/third-party-web/package/lib/markdown/updates/2019-05-13.md +14 -0
  381. package/lib/front_end/third_party/third-party-web/package/lib/markdown/updates/2021-01-01.md +1 -0
  382. package/lib/front_end/third_party/third-party-web/package/lib/markdown/updates/2024-07-01.md +3 -0
  383. package/lib/front_end/third_party/third-party-web/package/lib/subsets/httparchive-nostats.d.ts +1 -0
  384. package/lib/front_end/third_party/third-party-web/package/lib/subsets/httparchive-nostats.js +3 -0
  385. package/lib/front_end/third_party/third-party-web/package/lib/subsets/httparchive.d.ts +1 -0
  386. package/lib/front_end/third_party/third-party-web/package/lib/subsets/httparchive.js +3 -0
  387. package/lib/front_end/third_party/third-party-web/package/lib/subsets/nostats.d.ts +1 -0
  388. package/lib/front_end/third_party/third-party-web/package/lib/subsets/nostats.js +3 -0
  389. package/lib/front_end/third_party/third-party-web/package/nostats-subset.d.ts +1 -0
  390. package/lib/front_end/third_party/third-party-web/package/nostats-subset.js +1 -0
  391. package/lib/front_end/third_party/third-party-web/package/package.json +46 -0
  392. package/lib/front_end/third_party/third-party-web/package.json +8 -0
  393. package/lib/front_end/third_party/third-party-web/rebuild.sh +13 -0
  394. package/lib/front_end/third_party/third-party-web/third-party-web-tsconfig.json +8 -0
  395. package/lib/front_end/third_party/third-party-web/third-party-web.ts +3 -0
  396. package/package.json +24 -0
  397. package/patches/chrome-devtools-frontend+1.0.1533544.patch +187 -0
@@ -0,0 +1,1961 @@
1
+ // Copyright 2021 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ /*
6
+ * Copyright (C) 2009, 2010 Google Inc. All rights reserved.
7
+ * Copyright (C) 2009 Joseph Pecoraro
8
+ *
9
+ * Redistribution and use in source and binary forms, with or without
10
+ * modification, are permitted provided that the following conditions are
11
+ * met:
12
+ *
13
+ * * Redistributions of source code must retain the above copyright
14
+ * notice, this list of conditions and the following disclaimer.
15
+ * * Redistributions in binary form must reproduce the above
16
+ * copyright notice, this list of conditions and the following disclaimer
17
+ * in the documentation and/or other materials provided with the
18
+ * distribution.
19
+ * * Neither the #name of Google Inc. nor the names of its
20
+ * contributors may be used to endorse or promote products derived from
21
+ * this software without specific prior written permission.
22
+ *
23
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
+ */
35
+
36
+ import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js';
37
+ import * as Protocol from '../../generated/protocol.js';
38
+ import * as Common from '../common/common.js';
39
+ import * as Platform from '../platform/platform.js';
40
+ import * as Root from '../root/root.js';
41
+
42
+ import {CSSModel} from './CSSModel.js';
43
+ import {FrameManager} from './FrameManager.js';
44
+ import {OverlayModel} from './OverlayModel.js';
45
+ import {RemoteObject} from './RemoteObject.js';
46
+ import {ResourceTreeModel} from './ResourceTreeModel.js';
47
+ import {RuntimeModel} from './RuntimeModel.js';
48
+ import {SDKModel} from './SDKModel.js';
49
+ import {Capability, type Target} from './Target.js';
50
+ import {TargetManager} from './TargetManager.js';
51
+
52
+ /** Keep this list in sync with https://w3c.github.io/aria/#state_prop_def **/
53
+ export const ARIA_ATTRIBUTES = new Set<string>([
54
+ 'role',
55
+ 'aria-activedescendant',
56
+ 'aria-atomic',
57
+ 'aria-autocomplete',
58
+ 'aria-braillelabel',
59
+ 'aria-brailleroledescription',
60
+ 'aria-busy',
61
+ 'aria-checked',
62
+ 'aria-colcount',
63
+ 'aria-colindex',
64
+ 'aria-colindextext',
65
+ 'aria-colspan',
66
+ 'aria-controls',
67
+ 'aria-current',
68
+ 'aria-describedby',
69
+ 'aria-description',
70
+ 'aria-details',
71
+ 'aria-disabled',
72
+ 'aria-dropeffect',
73
+ 'aria-errormessage',
74
+ 'aria-expanded',
75
+ 'aria-flowto',
76
+ 'aria-grabbed',
77
+ 'aria-haspopup',
78
+ 'aria-hidden',
79
+ 'aria-invalid',
80
+ 'aria-keyshortcuts',
81
+ 'aria-label',
82
+ 'aria-labelledby',
83
+ 'aria-level',
84
+ 'aria-live',
85
+ 'aria-modal',
86
+ 'aria-multiline',
87
+ 'aria-multiselectable',
88
+ 'aria-orientation',
89
+ 'aria-owns',
90
+ 'aria-placeholder',
91
+ 'aria-posinset',
92
+ 'aria-pressed',
93
+ 'aria-readonly',
94
+ 'aria-relevant',
95
+ 'aria-required',
96
+ 'aria-roledescription',
97
+ 'aria-rowcount',
98
+ 'aria-rowindex',
99
+ 'aria-rowindextext',
100
+ 'aria-rowspan',
101
+ 'aria-selected',
102
+ 'aria-setsize',
103
+ 'aria-sort',
104
+ 'aria-valuemax',
105
+ 'aria-valuemin',
106
+ 'aria-valuenow',
107
+ 'aria-valuetext',
108
+ ]);
109
+
110
+ export class DOMNode {
111
+ #domModel: DOMModel;
112
+ #agent: ProtocolProxyApi.DOMApi;
113
+ ownerDocument!: DOMDocument|null;
114
+ #isInShadowTree!: boolean;
115
+ id!: Protocol.DOM.NodeId;
116
+ index: number|undefined = undefined;
117
+ #backendNodeId!: Protocol.DOM.BackendNodeId;
118
+ #nodeType!: number;
119
+ #nodeName!: string;
120
+ #localName!: string;
121
+ nodeValueInternal!: string;
122
+ #pseudoType!: Protocol.DOM.PseudoType|undefined;
123
+ #pseudoIdentifier?: string;
124
+ #shadowRootType!: Protocol.DOM.ShadowRootType|undefined;
125
+ #frameOwnerFrameId!: Protocol.Page.FrameId|null;
126
+ #xmlVersion!: string|undefined;
127
+ #isSVGNode!: boolean;
128
+ #isScrollable!: boolean;
129
+ #affectedByStartingStyles!: boolean;
130
+ #creationStackTrace: Promise<Protocol.Runtime.StackTrace|null>|null = null;
131
+ #pseudoElements = new Map<string, DOMNode[]>();
132
+ #distributedNodes: DOMNodeShortcut[] = [];
133
+ assignedSlot: DOMNodeShortcut|null = null;
134
+ readonly shadowRootsInternal: DOMNode[] = [];
135
+ #attributes = new Map<string, Attribute>();
136
+ #markers = new Map<string, unknown>();
137
+ #subtreeMarkerCount = 0;
138
+ childNodeCountInternal!: number;
139
+ childrenInternal: DOMNode[]|null = null;
140
+ nextSibling: DOMNode|null = null;
141
+ previousSibling: DOMNode|null = null;
142
+ firstChild: DOMNode|null = null;
143
+ lastChild: DOMNode|null = null;
144
+ parentNode: DOMNode|null = null;
145
+ templateContentInternal?: DOMNode;
146
+ contentDocumentInternal?: DOMDocument;
147
+ childDocumentPromiseForTesting?: Promise<DOMDocument|null>;
148
+ #importedDocument?: DOMNode;
149
+ publicId?: string;
150
+ systemId?: string;
151
+ internalSubset?: string;
152
+ name?: string;
153
+ value?: string;
154
+ /**
155
+ * Set when a DOMNode is retained in a detached sub-tree.
156
+ */
157
+ retained = false;
158
+ /**
159
+ * Set if a DOMNode is a root of a detached sub-tree.
160
+ */
161
+ detached = false;
162
+ #retainedNodes?: Set<Protocol.DOM.BackendNodeId>;
163
+
164
+ constructor(domModel: DOMModel) {
165
+ this.#domModel = domModel;
166
+ this.#agent = this.#domModel.getAgent();
167
+ }
168
+
169
+ static create(
170
+ domModel: DOMModel, doc: DOMDocument|null, isInShadowTree: boolean, payload: Protocol.DOM.Node,
171
+ retainedNodes?: Set<Protocol.DOM.BackendNodeId>): DOMNode {
172
+ const node = new DOMNode(domModel);
173
+ node.init(doc, isInShadowTree, payload, retainedNodes);
174
+ return node;
175
+ }
176
+
177
+ init(
178
+ doc: DOMDocument|null, isInShadowTree: boolean, payload: Protocol.DOM.Node,
179
+ retainedNodes?: Set<Protocol.DOM.BackendNodeId>): void {
180
+ this.#agent = this.#domModel.getAgent();
181
+ this.ownerDocument = doc;
182
+ this.#isInShadowTree = isInShadowTree;
183
+
184
+ this.id = payload.nodeId;
185
+ this.#backendNodeId = payload.backendNodeId;
186
+ this.#domModel.registerNode(this);
187
+ this.#nodeType = payload.nodeType;
188
+ this.#nodeName = payload.nodeName;
189
+ this.#localName = payload.localName;
190
+ this.nodeValueInternal = payload.nodeValue;
191
+ this.#pseudoType = payload.pseudoType;
192
+ this.#pseudoIdentifier = payload.pseudoIdentifier;
193
+ this.#shadowRootType = payload.shadowRootType;
194
+ this.#frameOwnerFrameId = payload.frameId || null;
195
+ this.#xmlVersion = payload.xmlVersion;
196
+ this.#isSVGNode = Boolean(payload.isSVG);
197
+ this.#isScrollable = Boolean(payload.isScrollable);
198
+ this.#affectedByStartingStyles = Boolean(payload.affectedByStartingStyles);
199
+ this.#retainedNodes = retainedNodes;
200
+
201
+ if (this.#retainedNodes?.has(this.backendNodeId())) {
202
+ this.retained = true;
203
+ }
204
+
205
+ if (payload.attributes) {
206
+ this.setAttributesPayload(payload.attributes);
207
+ }
208
+
209
+ this.childNodeCountInternal = payload.childNodeCount || 0;
210
+ if (payload.shadowRoots) {
211
+ for (let i = 0; i < payload.shadowRoots.length; ++i) {
212
+ const root = payload.shadowRoots[i];
213
+ const node = DOMNode.create(this.#domModel, this.ownerDocument, true, root, retainedNodes);
214
+ this.shadowRootsInternal.push(node);
215
+ node.parentNode = this;
216
+ }
217
+ }
218
+
219
+ if (payload.templateContent) {
220
+ this.templateContentInternal =
221
+ DOMNode.create(this.#domModel, this.ownerDocument, true, payload.templateContent, retainedNodes);
222
+ this.templateContentInternal.parentNode = this;
223
+ this.childrenInternal = [];
224
+ }
225
+
226
+ const frameOwnerTags = new Set(['EMBED', 'IFRAME', 'OBJECT', 'FENCEDFRAME']);
227
+ if (payload.contentDocument) {
228
+ this.contentDocumentInternal = new DOMDocument(this.#domModel, payload.contentDocument);
229
+ this.contentDocumentInternal.parentNode = this;
230
+ this.childrenInternal = [];
231
+ } else if (payload.frameId && frameOwnerTags.has(payload.nodeName)) {
232
+ // At this point we know we are in an OOPIF, otherwise `payload.contentDocument` would have been set.
233
+ this.childDocumentPromiseForTesting = this.requestChildDocument(payload.frameId, this.#domModel.target());
234
+ this.childrenInternal = [];
235
+ }
236
+
237
+ if (payload.importedDocument) {
238
+ this.#importedDocument =
239
+ DOMNode.create(this.#domModel, this.ownerDocument, true, payload.importedDocument, retainedNodes);
240
+ this.#importedDocument.parentNode = this;
241
+ this.childrenInternal = [];
242
+ }
243
+
244
+ if (payload.distributedNodes) {
245
+ this.setDistributedNodePayloads(payload.distributedNodes);
246
+ }
247
+
248
+ if (payload.assignedSlot) {
249
+ this.setAssignedSlot(payload.assignedSlot);
250
+ }
251
+
252
+ if (payload.children) {
253
+ this.setChildrenPayload(payload.children);
254
+ }
255
+
256
+ this.setPseudoElements(payload.pseudoElements);
257
+
258
+ if (this.#nodeType === Node.ELEMENT_NODE) {
259
+ // HTML and BODY from internal iframes should not overwrite top-level ones.
260
+ if (this.ownerDocument && !this.ownerDocument.documentElement && this.#nodeName === 'HTML') {
261
+ this.ownerDocument.documentElement = this;
262
+ }
263
+ if (this.ownerDocument && !this.ownerDocument.body && this.#nodeName === 'BODY') {
264
+ this.ownerDocument.body = this;
265
+ }
266
+ } else if (this.#nodeType === Node.DOCUMENT_TYPE_NODE) {
267
+ this.publicId = payload.publicId;
268
+ this.systemId = payload.systemId;
269
+ this.internalSubset = payload.internalSubset;
270
+ } else if (this.#nodeType === Node.ATTRIBUTE_NODE) {
271
+ this.name = payload.name;
272
+ this.value = payload.value;
273
+ }
274
+ }
275
+
276
+ private async requestChildDocument(frameId: Protocol.Page.FrameId, notInTarget: Target): Promise<DOMDocument|null> {
277
+ const frame = await FrameManager.instance().getOrWaitForFrame(frameId, notInTarget);
278
+ const childModel = frame.resourceTreeModel()?.target().model(DOMModel);
279
+ return await (childModel?.requestDocument() || null);
280
+ }
281
+
282
+ isAdFrameNode(): boolean {
283
+ if (this.isIframe() && this.#frameOwnerFrameId) {
284
+ const frame = FrameManager.instance().getFrame(this.#frameOwnerFrameId);
285
+ if (!frame) {
286
+ return false;
287
+ }
288
+ return frame.adFrameType() !== Protocol.Page.AdFrameType.None;
289
+ }
290
+ return false;
291
+ }
292
+
293
+ isSVGNode(): boolean {
294
+ return this.#isSVGNode;
295
+ }
296
+
297
+ isScrollable(): boolean {
298
+ return this.#isScrollable;
299
+ }
300
+
301
+ affectedByStartingStyles(): boolean {
302
+ return this.#affectedByStartingStyles;
303
+ }
304
+
305
+ isMediaNode(): boolean {
306
+ return this.#nodeName === 'AUDIO' || this.#nodeName === 'VIDEO';
307
+ }
308
+
309
+ isViewTransitionPseudoNode(): boolean {
310
+ if (!this.#pseudoType) {
311
+ return false;
312
+ }
313
+
314
+ return [
315
+ Protocol.DOM.PseudoType.ViewTransition,
316
+ Protocol.DOM.PseudoType.ViewTransitionGroup,
317
+ Protocol.DOM.PseudoType.ViewTransitionGroupChildren,
318
+ Protocol.DOM.PseudoType.ViewTransitionImagePair,
319
+ Protocol.DOM.PseudoType.ViewTransitionOld,
320
+ Protocol.DOM.PseudoType.ViewTransitionNew,
321
+ ].includes(this.#pseudoType);
322
+ }
323
+
324
+ creationStackTrace(): Promise<Protocol.Runtime.StackTrace|null> {
325
+ if (this.#creationStackTrace) {
326
+ return this.#creationStackTrace;
327
+ }
328
+
329
+ const stackTracesPromise = this.#agent.invoke_getNodeStackTraces({nodeId: this.id});
330
+ this.#creationStackTrace = stackTracesPromise.then(res => res.creation || null);
331
+ return this.#creationStackTrace;
332
+ }
333
+
334
+ get subtreeMarkerCount(): number {
335
+ return this.#subtreeMarkerCount;
336
+ }
337
+
338
+ domModel(): DOMModel {
339
+ return this.#domModel;
340
+ }
341
+
342
+ backendNodeId(): Protocol.DOM.BackendNodeId {
343
+ return this.#backendNodeId;
344
+ }
345
+
346
+ children(): DOMNode[]|null {
347
+ return this.childrenInternal ? this.childrenInternal.slice() : null;
348
+ }
349
+
350
+ setChildren(children: DOMNode[]): void {
351
+ this.childrenInternal = children;
352
+ }
353
+
354
+ setIsScrollable(isScrollable: boolean): void {
355
+ this.#isScrollable = isScrollable;
356
+ }
357
+
358
+ setAffectedByStartingStyles(affectedByStartingStyles: boolean): void {
359
+ this.#affectedByStartingStyles = affectedByStartingStyles;
360
+ }
361
+
362
+ hasAttributes(): boolean {
363
+ return this.#attributes.size > 0;
364
+ }
365
+
366
+ childNodeCount(): number {
367
+ return this.childNodeCountInternal;
368
+ }
369
+
370
+ setChildNodeCount(childNodeCount: number): void {
371
+ this.childNodeCountInternal = childNodeCount;
372
+ }
373
+
374
+ shadowRoots(): DOMNode[] {
375
+ return this.shadowRootsInternal.slice();
376
+ }
377
+
378
+ templateContent(): DOMNode|null {
379
+ return this.templateContentInternal || null;
380
+ }
381
+
382
+ contentDocument(): DOMDocument|null {
383
+ return this.contentDocumentInternal || null;
384
+ }
385
+
386
+ setContentDocument(node: DOMDocument): void {
387
+ this.contentDocumentInternal = node;
388
+ }
389
+
390
+ isIframe(): boolean {
391
+ return this.#nodeName === 'IFRAME';
392
+ }
393
+
394
+ importedDocument(): DOMNode|null {
395
+ return this.#importedDocument || null;
396
+ }
397
+
398
+ nodeType(): number {
399
+ return this.#nodeType;
400
+ }
401
+
402
+ nodeName(): string {
403
+ return this.#nodeName;
404
+ }
405
+
406
+ pseudoType(): string|undefined {
407
+ return this.#pseudoType;
408
+ }
409
+
410
+ pseudoIdentifier(): string|undefined {
411
+ return this.#pseudoIdentifier;
412
+ }
413
+
414
+ hasPseudoElements(): boolean {
415
+ return this.#pseudoElements.size > 0;
416
+ }
417
+
418
+ pseudoElements(): Map<string, DOMNode[]> {
419
+ return this.#pseudoElements;
420
+ }
421
+
422
+ checkmarkPseudoElement(): DOMNode|undefined {
423
+ return this.#pseudoElements.get(Protocol.DOM.PseudoType.Checkmark)?.at(-1);
424
+ }
425
+
426
+ beforePseudoElement(): DOMNode|undefined {
427
+ return this.#pseudoElements.get(Protocol.DOM.PseudoType.Before)?.at(-1);
428
+ }
429
+
430
+ afterPseudoElement(): DOMNode|undefined {
431
+ return this.#pseudoElements.get(Protocol.DOM.PseudoType.After)?.at(-1);
432
+ }
433
+
434
+ pickerIconPseudoElement(): DOMNode|undefined {
435
+ return this.#pseudoElements.get(Protocol.DOM.PseudoType.PickerIcon)?.at(-1);
436
+ }
437
+
438
+ markerPseudoElement(): DOMNode|undefined {
439
+ return this.#pseudoElements.get(Protocol.DOM.PseudoType.Marker)?.at(-1);
440
+ }
441
+
442
+ backdropPseudoElement(): DOMNode|undefined {
443
+ return this.#pseudoElements.get(Protocol.DOM.PseudoType.Backdrop)?.at(-1);
444
+ }
445
+
446
+ viewTransitionPseudoElements(): DOMNode[] {
447
+ return [
448
+ ...this.#pseudoElements.get(Protocol.DOM.PseudoType.ViewTransition) || [],
449
+ ...this.#pseudoElements.get(Protocol.DOM.PseudoType.ViewTransitionGroup) || [],
450
+ ...this.#pseudoElements.get(Protocol.DOM.PseudoType.ViewTransitionGroupChildren) || [],
451
+ ...this.#pseudoElements.get(Protocol.DOM.PseudoType.ViewTransitionImagePair) || [],
452
+ ...this.#pseudoElements.get(Protocol.DOM.PseudoType.ViewTransitionOld) || [],
453
+ ...this.#pseudoElements.get(Protocol.DOM.PseudoType.ViewTransitionNew) || [],
454
+ ];
455
+ }
456
+
457
+ carouselPseudoElements(): DOMNode[] {
458
+ return [
459
+ ...this.#pseudoElements.get(Protocol.DOM.PseudoType.ScrollButton) || [],
460
+ ...this.#pseudoElements.get(Protocol.DOM.PseudoType.Column) || [],
461
+ ...this.#pseudoElements.get(Protocol.DOM.PseudoType.ScrollMarker) || [],
462
+ ...this.#pseudoElements.get(Protocol.DOM.PseudoType.ScrollMarkerGroup) || [],
463
+ ];
464
+ }
465
+
466
+ hasAssignedSlot(): boolean {
467
+ return this.assignedSlot !== null;
468
+ }
469
+
470
+ isInsertionPoint(): boolean {
471
+ return !this.isXMLNode() &&
472
+ (this.#nodeName === 'SHADOW' || this.#nodeName === 'CONTENT' || this.#nodeName === 'SLOT');
473
+ }
474
+
475
+ distributedNodes(): DOMNodeShortcut[] {
476
+ return this.#distributedNodes;
477
+ }
478
+
479
+ isInShadowTree(): boolean {
480
+ return this.#isInShadowTree;
481
+ }
482
+
483
+ getTreeRoot(): DOMNode {
484
+ return this.isShadowRoot() ? this : (this.ancestorShadowRoot() ?? this.ownerDocument ?? this);
485
+ }
486
+
487
+ ancestorShadowHost(): DOMNode|null {
488
+ const ancestorShadowRoot = this.ancestorShadowRoot();
489
+ return ancestorShadowRoot ? ancestorShadowRoot.parentNode : null;
490
+ }
491
+
492
+ ancestorShadowRoot(): DOMNode|null {
493
+ if (!this.#isInShadowTree) {
494
+ return null;
495
+ }
496
+
497
+ let current: DOMNode|null = this;
498
+ while (current && !current.isShadowRoot()) {
499
+ current = current.parentNode;
500
+ }
501
+ return current;
502
+ }
503
+
504
+ ancestorUserAgentShadowRoot(): DOMNode|null {
505
+ const ancestorShadowRoot = this.ancestorShadowRoot();
506
+ if (!ancestorShadowRoot) {
507
+ return null;
508
+ }
509
+ return ancestorShadowRoot.shadowRootType() === DOMNode.ShadowRootTypes.UserAgent ? ancestorShadowRoot : null;
510
+ }
511
+
512
+ isShadowRoot(): boolean {
513
+ return Boolean(this.#shadowRootType);
514
+ }
515
+
516
+ shadowRootType(): string|null {
517
+ return this.#shadowRootType || null;
518
+ }
519
+
520
+ nodeNameInCorrectCase(): string {
521
+ const shadowRootType = this.shadowRootType();
522
+ if (shadowRootType) {
523
+ return '#shadow-root (' + shadowRootType + ')';
524
+ }
525
+
526
+ // If there is no local #name, it's case sensitive
527
+ if (!this.localName()) {
528
+ return this.nodeName();
529
+ }
530
+
531
+ // If the names are different lengths, there is a prefix and it's case sensitive
532
+ if (this.localName().length !== this.nodeName().length) {
533
+ return this.nodeName();
534
+ }
535
+
536
+ // Return the localname, which will be case insensitive if its an html node
537
+ return this.localName();
538
+ }
539
+
540
+ setNodeName(name: string, callback?: ((arg0: string|null, arg1: DOMNode|null) => void)): void {
541
+ void this.#agent.invoke_setNodeName({nodeId: this.id, name}).then(response => {
542
+ if (!response.getError()) {
543
+ this.#domModel.markUndoableState();
544
+ }
545
+ if (callback) {
546
+ callback(response.getError() || null, this.#domModel.nodeForId(response.nodeId));
547
+ }
548
+ });
549
+ }
550
+
551
+ localName(): string {
552
+ return this.#localName;
553
+ }
554
+
555
+ nodeValue(): string {
556
+ return this.nodeValueInternal;
557
+ }
558
+
559
+ setNodeValueInternal(nodeValue: string): void {
560
+ this.nodeValueInternal = nodeValue;
561
+ }
562
+
563
+ setNodeValue(value: string, callback?: ((arg0: string|null) => void)): void {
564
+ void this.#agent.invoke_setNodeValue({nodeId: this.id, value}).then(response => {
565
+ if (!response.getError()) {
566
+ this.#domModel.markUndoableState();
567
+ }
568
+ if (callback) {
569
+ callback(response.getError() || null);
570
+ }
571
+ });
572
+ }
573
+
574
+ getAttribute(name: string): string|undefined {
575
+ const attr = this.#attributes.get(name);
576
+ return attr ? attr.value : undefined;
577
+ }
578
+
579
+ setAttribute(name: string, text: string, callback?: ((arg0: string|null) => void)): void {
580
+ void this.#agent.invoke_setAttributesAsText({nodeId: this.id, text, name}).then(response => {
581
+ if (!response.getError()) {
582
+ this.#domModel.markUndoableState();
583
+ }
584
+ if (callback) {
585
+ callback(response.getError() || null);
586
+ }
587
+ });
588
+ }
589
+
590
+ setAttributeValue(name: string, value: string, callback?: ((arg0: string|null) => void)): void {
591
+ void this.#agent.invoke_setAttributeValue({nodeId: this.id, name, value}).then(response => {
592
+ if (!response.getError()) {
593
+ this.#domModel.markUndoableState();
594
+ }
595
+ if (callback) {
596
+ callback(response.getError() || null);
597
+ }
598
+ });
599
+ }
600
+
601
+ setAttributeValuePromise(name: string, value: string): Promise<string|null> {
602
+ return new Promise(fulfill => this.setAttributeValue(name, value, fulfill));
603
+ }
604
+
605
+ attributes(): Attribute[] {
606
+ return [...this.#attributes.values()];
607
+ }
608
+
609
+ async removeAttribute(name: string): Promise<void> {
610
+ const response = await this.#agent.invoke_removeAttribute({nodeId: this.id, name});
611
+ if (response.getError()) {
612
+ return;
613
+ }
614
+ this.#attributes.delete(name);
615
+ this.#domModel.markUndoableState();
616
+ }
617
+
618
+ getChildNodesPromise(): Promise<DOMNode[]|null> {
619
+ return new Promise(resolve => {
620
+ return this.getChildNodes(childNodes => resolve(childNodes));
621
+ });
622
+ }
623
+
624
+ getChildNodes(callback: (arg0: DOMNode[]|null) => void): void {
625
+ if (this.childrenInternal) {
626
+ callback(this.children());
627
+ return;
628
+ }
629
+ void this.#agent.invoke_requestChildNodes({nodeId: this.id}).then(response => {
630
+ callback(response.getError() ? null : this.children());
631
+ });
632
+ }
633
+
634
+ async getSubtree(depth: number, pierce: boolean): Promise<DOMNode[]|null> {
635
+ const response = await this.#agent.invoke_requestChildNodes({nodeId: this.id, depth, pierce});
636
+ return response.getError() ? null : this.childrenInternal;
637
+ }
638
+
639
+ async getOuterHTML(includeShadowDOM = false): Promise<string|null> {
640
+ const {outerHTML} = await this.#agent.invoke_getOuterHTML({nodeId: this.id, includeShadowDOM});
641
+ return outerHTML;
642
+ }
643
+
644
+ setOuterHTML(html: string, callback?: ((arg0: string|null) => void)): void {
645
+ void this.#agent.invoke_setOuterHTML({nodeId: this.id, outerHTML: html}).then(response => {
646
+ if (!response.getError()) {
647
+ this.#domModel.markUndoableState();
648
+ }
649
+ if (callback) {
650
+ callback(response.getError() || null);
651
+ }
652
+ });
653
+ }
654
+
655
+ removeNode(callback?: ((arg0: string|null, arg1?: Protocol.DOM.NodeId|undefined) => void)): Promise<void> {
656
+ return this.#agent.invoke_removeNode({nodeId: this.id}).then(response => {
657
+ if (!response.getError()) {
658
+ this.#domModel.markUndoableState();
659
+ }
660
+ if (callback) {
661
+ callback(response.getError() || null);
662
+ }
663
+ });
664
+ }
665
+
666
+ path(): string {
667
+ function getNodeKey(node: DOMNode): number|'u'|'a'|'d'|null {
668
+ if (!node.#nodeName.length) {
669
+ return null;
670
+ }
671
+ if (node.index !== undefined) {
672
+ return node.index;
673
+ }
674
+ if (!node.parentNode) {
675
+ return null;
676
+ }
677
+ if (node.isShadowRoot()) {
678
+ return node.shadowRootType() === DOMNode.ShadowRootTypes.UserAgent ? 'u' : 'a';
679
+ }
680
+ if (node.nodeType() === Node.DOCUMENT_NODE) {
681
+ return 'd';
682
+ }
683
+ return null;
684
+ }
685
+
686
+ const path = [];
687
+ let node: (DOMNode|null) = this;
688
+ while (node) {
689
+ const key = getNodeKey(node);
690
+ if (key === null) {
691
+ break;
692
+ }
693
+
694
+ path.push([key, node.#nodeName]);
695
+ node = node.parentNode;
696
+ }
697
+ path.reverse();
698
+ return path.join(',');
699
+ }
700
+
701
+ isAncestor(node: DOMNode): boolean {
702
+ if (!node) {
703
+ return false;
704
+ }
705
+
706
+ let currentNode: (DOMNode|null) = node.parentNode;
707
+ while (currentNode) {
708
+ if (this === currentNode) {
709
+ return true;
710
+ }
711
+ currentNode = currentNode.parentNode;
712
+ }
713
+ return false;
714
+ }
715
+
716
+ isDescendant(descendant: DOMNode): boolean {
717
+ return descendant.isAncestor(this);
718
+ }
719
+
720
+ frameOwnerFrameId(): Protocol.Page.FrameId|null {
721
+ return this.#frameOwnerFrameId;
722
+ }
723
+
724
+ frameId(): Protocol.Page.FrameId|null {
725
+ let node: DOMNode = this.parentNode || this;
726
+ while (!node.#frameOwnerFrameId && node.parentNode) {
727
+ node = node.parentNode;
728
+ }
729
+ return node.#frameOwnerFrameId;
730
+ }
731
+
732
+ setAttributesPayload(attrs: string[]): boolean {
733
+ let attributesChanged: true|boolean = !this.#attributes || attrs.length !== this.#attributes.size * 2;
734
+ const oldAttributesMap = this.#attributes || new Map();
735
+
736
+ this.#attributes = new Map();
737
+
738
+ for (let i = 0; i < attrs.length; i += 2) {
739
+ const name = attrs[i];
740
+ const value = attrs[i + 1];
741
+ this.addAttribute(name, value);
742
+
743
+ if (attributesChanged) {
744
+ continue;
745
+ }
746
+
747
+ const oldAttribute = oldAttributesMap.get(name);
748
+ if (!oldAttribute || oldAttribute.value !== value) {
749
+ attributesChanged = true;
750
+ }
751
+ }
752
+ return attributesChanged;
753
+ }
754
+
755
+ insertChild(prev: DOMNode|undefined, payload: Protocol.DOM.Node): DOMNode {
756
+ if (!this.childrenInternal) {
757
+ throw new Error('DOMNode._children is expected to not be null.');
758
+ }
759
+ const node = DOMNode.create(this.#domModel, this.ownerDocument, this.#isInShadowTree, payload, this.#retainedNodes);
760
+ this.childrenInternal.splice(prev ? this.childrenInternal.indexOf(prev) + 1 : 0, 0, node);
761
+ this.renumber();
762
+ return node;
763
+ }
764
+
765
+ removeChild(node: DOMNode): void {
766
+ const pseudoType = node.pseudoType();
767
+ if (pseudoType) {
768
+ const updatedPseudoElements = this.#pseudoElements.get(pseudoType)?.filter(element => element !== node);
769
+ if (updatedPseudoElements && updatedPseudoElements.length > 0) {
770
+ this.#pseudoElements.set(pseudoType, updatedPseudoElements);
771
+ } else {
772
+ this.#pseudoElements.delete(pseudoType);
773
+ }
774
+ } else {
775
+ const shadowRootIndex = this.shadowRootsInternal.indexOf(node);
776
+ if (shadowRootIndex !== -1) {
777
+ this.shadowRootsInternal.splice(shadowRootIndex, 1);
778
+ } else {
779
+ if (!this.childrenInternal) {
780
+ throw new Error('DOMNode._children is expected to not be null.');
781
+ }
782
+ if (this.childrenInternal.indexOf(node) === -1) {
783
+ throw new Error('DOMNode._children is expected to contain the node to be removed.');
784
+ }
785
+ this.childrenInternal.splice(this.childrenInternal.indexOf(node), 1);
786
+ }
787
+ }
788
+ node.parentNode = null;
789
+ this.#subtreeMarkerCount -= node.#subtreeMarkerCount;
790
+ if (node.#subtreeMarkerCount) {
791
+ this.#domModel.dispatchEventToListeners(Events.MarkersChanged, this);
792
+ }
793
+ this.renumber();
794
+ }
795
+
796
+ setChildrenPayload(payloads: Protocol.DOM.Node[]): void {
797
+ this.childrenInternal = [];
798
+ for (let i = 0; i < payloads.length; ++i) {
799
+ const payload = payloads[i];
800
+ const node =
801
+ DOMNode.create(this.#domModel, this.ownerDocument, this.#isInShadowTree, payload, this.#retainedNodes);
802
+ this.childrenInternal.push(node);
803
+ }
804
+ this.renumber();
805
+ }
806
+
807
+ private setPseudoElements(payloads: Protocol.DOM.Node[]|undefined): void {
808
+ if (!payloads) {
809
+ return;
810
+ }
811
+
812
+ for (let i = 0; i < payloads.length; ++i) {
813
+ const node =
814
+ DOMNode.create(this.#domModel, this.ownerDocument, this.#isInShadowTree, payloads[i], this.#retainedNodes);
815
+ node.parentNode = this;
816
+ const pseudoType = node.pseudoType();
817
+ if (!pseudoType) {
818
+ throw new Error('DOMNode.pseudoType() is expected to be defined.');
819
+ }
820
+ const currentPseudoElements = this.#pseudoElements.get(pseudoType);
821
+ if (currentPseudoElements) {
822
+ currentPseudoElements.push(node);
823
+ } else {
824
+ this.#pseudoElements.set(pseudoType, [node]);
825
+ }
826
+ }
827
+ }
828
+
829
+ setDistributedNodePayloads(payloads: Protocol.DOM.BackendNode[]): void {
830
+ this.#distributedNodes = [];
831
+ for (const payload of payloads) {
832
+ this.#distributedNodes.push(
833
+ new DOMNodeShortcut(this.#domModel.target(), payload.backendNodeId, payload.nodeType, payload.nodeName));
834
+ }
835
+ }
836
+
837
+ setAssignedSlot(payload: Protocol.DOM.BackendNode): void {
838
+ this.assignedSlot =
839
+ new DOMNodeShortcut(this.#domModel.target(), payload.backendNodeId, payload.nodeType, payload.nodeName);
840
+ }
841
+
842
+ private renumber(): void {
843
+ if (!this.childrenInternal) {
844
+ throw new Error('DOMNode._children is expected to not be null.');
845
+ }
846
+ this.childNodeCountInternal = this.childrenInternal.length;
847
+ if (this.childNodeCountInternal === 0) {
848
+ this.firstChild = null;
849
+ this.lastChild = null;
850
+ return;
851
+ }
852
+ this.firstChild = this.childrenInternal[0];
853
+ this.lastChild = this.childrenInternal[this.childNodeCountInternal - 1];
854
+ for (let i = 0; i < this.childNodeCountInternal; ++i) {
855
+ const child = this.childrenInternal[i];
856
+ child.index = i;
857
+ child.nextSibling = i + 1 < this.childNodeCountInternal ? this.childrenInternal[i + 1] : null;
858
+ child.previousSibling = i - 1 >= 0 ? this.childrenInternal[i - 1] : null;
859
+ child.parentNode = this;
860
+ }
861
+ }
862
+
863
+ private addAttribute(name: string, value: string): void {
864
+ const attr = {name, value, _node: this};
865
+ this.#attributes.set(name, attr);
866
+ }
867
+
868
+ setAttributeInternal(name: string, value: string): void {
869
+ const attr = this.#attributes.get(name);
870
+ if (attr) {
871
+ attr.value = value;
872
+ } else {
873
+ this.addAttribute(name, value);
874
+ }
875
+ }
876
+
877
+ removeAttributeInternal(name: string): void {
878
+ this.#attributes.delete(name);
879
+ }
880
+
881
+ copyTo(targetNode: DOMNode, anchorNode: DOMNode|null, callback?: ((arg0: string|null, arg1: DOMNode|null) => void)):
882
+ void {
883
+ void this.#agent
884
+ .invoke_copyTo(
885
+ {nodeId: this.id, targetNodeId: targetNode.id, insertBeforeNodeId: anchorNode ? anchorNode.id : undefined})
886
+ .then(response => {
887
+ if (!response.getError()) {
888
+ this.#domModel.markUndoableState();
889
+ }
890
+ const pastedNode = this.#domModel.nodeForId(response.nodeId);
891
+ if (pastedNode) {
892
+ // For every marker in this.#markers, set a marker in the copied node.
893
+ for (const [name, value] of this.#markers) {
894
+ pastedNode.setMarker(name, value);
895
+ }
896
+ }
897
+ if (callback) {
898
+ callback(response.getError() || null, pastedNode);
899
+ }
900
+ });
901
+ }
902
+
903
+ moveTo(targetNode: DOMNode, anchorNode: DOMNode|null, callback?: ((arg0: string|null, arg1: DOMNode|null) => void)):
904
+ void {
905
+ void this.#agent
906
+ .invoke_moveTo(
907
+ {nodeId: this.id, targetNodeId: targetNode.id, insertBeforeNodeId: anchorNode ? anchorNode.id : undefined})
908
+ .then(response => {
909
+ if (!response.getError()) {
910
+ this.#domModel.markUndoableState();
911
+ }
912
+ if (callback) {
913
+ callback(response.getError() || null, this.#domModel.nodeForId(response.nodeId));
914
+ }
915
+ });
916
+ }
917
+
918
+ isXMLNode(): boolean {
919
+ return Boolean(this.#xmlVersion);
920
+ }
921
+
922
+ setMarker(name: string, value: unknown): void {
923
+ if (value === null) {
924
+ if (!this.#markers.has(name)) {
925
+ return;
926
+ }
927
+
928
+ this.#markers.delete(name);
929
+ for (let node: (DOMNode|null) = this; node; node = node.parentNode) {
930
+ --node.#subtreeMarkerCount;
931
+ }
932
+ for (let node: (DOMNode|null) = this; node; node = node.parentNode) {
933
+ this.#domModel.dispatchEventToListeners(Events.MarkersChanged, node);
934
+ }
935
+ return;
936
+ }
937
+
938
+ if (this.parentNode && !this.#markers.has(name)) {
939
+ for (let node: (DOMNode|null) = this; node; node = node.parentNode) {
940
+ ++node.#subtreeMarkerCount;
941
+ }
942
+ }
943
+ this.#markers.set(name, value);
944
+ for (let node: (DOMNode|null) = this; node; node = node.parentNode) {
945
+ this.#domModel.dispatchEventToListeners(Events.MarkersChanged, node);
946
+ }
947
+ }
948
+
949
+ marker<T>(name: string): T|null {
950
+ return this.#markers.get(name) as T || null;
951
+ }
952
+
953
+ getMarkerKeysForTest(): string[] {
954
+ return [...this.#markers.keys()];
955
+ }
956
+
957
+ traverseMarkers(visitor: (arg0: DOMNode, arg1: string) => void): void {
958
+ function traverse(node: DOMNode): void {
959
+ if (!node.#subtreeMarkerCount) {
960
+ return;
961
+ }
962
+ for (const marker of node.#markers.keys()) {
963
+ visitor(node, marker);
964
+ }
965
+ if (!node.childrenInternal) {
966
+ return;
967
+ }
968
+ for (const child of node.childrenInternal) {
969
+ traverse(child);
970
+ }
971
+ }
972
+ traverse(this);
973
+ }
974
+
975
+ resolveURL(url: string): Platform.DevToolsPath.UrlString|null {
976
+ if (!url) {
977
+ return url as Platform.DevToolsPath.UrlString;
978
+ }
979
+ for (let frameOwnerCandidate: (DOMNode|null) = this; frameOwnerCandidate;
980
+ frameOwnerCandidate = frameOwnerCandidate.parentNode) {
981
+ if (frameOwnerCandidate instanceof DOMDocument && frameOwnerCandidate.baseURL) {
982
+ return Common.ParsedURL.ParsedURL.completeURL(frameOwnerCandidate.baseURL, url);
983
+ }
984
+ }
985
+ return null;
986
+ }
987
+
988
+ highlight(mode?: string): void {
989
+ this.#domModel.overlayModel().highlightInOverlay({node: this, selectorList: undefined}, mode);
990
+ }
991
+
992
+ highlightForTwoSeconds(): void {
993
+ this.#domModel.overlayModel().highlightInOverlayForTwoSeconds({node: this, selectorList: undefined});
994
+ }
995
+
996
+ async resolveToObject(objectGroup?: string, executionContextId?: Protocol.Runtime.ExecutionContextId):
997
+ Promise<RemoteObject|null> {
998
+ const {object} = await this.#agent.invoke_resolveNode(
999
+ {nodeId: this.id, backendNodeId: undefined, executionContextId, objectGroup});
1000
+ return object && this.#domModel.runtimeModelInternal.createRemoteObject(object) || null;
1001
+ }
1002
+
1003
+ async boxModel(): Promise<Protocol.DOM.BoxModel|null> {
1004
+ const {model} = await this.#agent.invoke_getBoxModel({nodeId: this.id});
1005
+ return model;
1006
+ }
1007
+
1008
+ async setAsInspectedNode(): Promise<void> {
1009
+ let node: DOMNode|null = this;
1010
+ if (node?.pseudoType()) {
1011
+ node = node.parentNode;
1012
+ }
1013
+ while (node) {
1014
+ let ancestor = node.ancestorUserAgentShadowRoot();
1015
+ if (!ancestor) {
1016
+ break;
1017
+ }
1018
+ ancestor = node.ancestorShadowHost();
1019
+ if (!ancestor) {
1020
+ break;
1021
+ }
1022
+ // User #agent shadow root, keep climbing up.
1023
+ node = ancestor;
1024
+ }
1025
+ if (!node) {
1026
+ throw new Error('In DOMNode.setAsInspectedNode: node is expected to not be null.');
1027
+ }
1028
+ await this.#agent.invoke_setInspectedNode({nodeId: node.id});
1029
+ }
1030
+
1031
+ enclosingElementOrSelf(): DOMNode|null {
1032
+ let node: DOMNode|null = this;
1033
+ if (node && node.nodeType() === Node.TEXT_NODE && node.parentNode) {
1034
+ node = node.parentNode;
1035
+ }
1036
+
1037
+ if (node && node.nodeType() !== Node.ELEMENT_NODE) {
1038
+ node = null;
1039
+ }
1040
+ return node;
1041
+ }
1042
+
1043
+ async callFunction<T, U extends string|number>(fn: (this: HTMLElement, ...args: U[]) => T, args: U[] = []):
1044
+ Promise<{value: T}|null> {
1045
+ const object = await this.resolveToObject();
1046
+ if (!object) {
1047
+ return null;
1048
+ }
1049
+
1050
+ const result = await object.callFunction(fn, args.map(arg => RemoteObject.toCallArgument(arg)));
1051
+ object.release();
1052
+ if (result.wasThrown || !result.object) {
1053
+ return null;
1054
+ }
1055
+ return {
1056
+ value: result.object.value as T,
1057
+ };
1058
+ }
1059
+
1060
+ async scrollIntoView(): Promise<void> {
1061
+ const node = this.enclosingElementOrSelf();
1062
+ if (!node) {
1063
+ return;
1064
+ }
1065
+
1066
+ const result = await node.callFunction(scrollIntoViewInPage);
1067
+ if (!result) {
1068
+ return;
1069
+ }
1070
+
1071
+ node.highlightForTwoSeconds();
1072
+
1073
+ function scrollIntoViewInPage(this: Element): void {
1074
+ this.scrollIntoViewIfNeeded(true);
1075
+ }
1076
+ }
1077
+
1078
+ async focus(): Promise<void> {
1079
+ const node = this.enclosingElementOrSelf();
1080
+ if (!node) {
1081
+ throw new Error('DOMNode.focus expects node to not be null.');
1082
+ }
1083
+ const result = await node.callFunction(focusInPage);
1084
+ if (!result) {
1085
+ return;
1086
+ }
1087
+
1088
+ node.highlightForTwoSeconds();
1089
+ await this.#domModel.target().pageAgent().invoke_bringToFront();
1090
+
1091
+ function focusInPage(this: HTMLElement): void {
1092
+ this.focus();
1093
+ }
1094
+ }
1095
+
1096
+ simpleSelector(): string {
1097
+ const lowerCaseName = this.localName() || this.nodeName().toLowerCase();
1098
+ if (this.nodeType() !== Node.ELEMENT_NODE) {
1099
+ return lowerCaseName;
1100
+ }
1101
+ const type = this.getAttribute('type');
1102
+ const id = this.getAttribute('id');
1103
+ const classes = this.getAttribute('class');
1104
+
1105
+ if (lowerCaseName === 'input' && type && !id && !classes) {
1106
+ return lowerCaseName + '[type="' + CSS.escape(type) + '"]';
1107
+ }
1108
+ if (id) {
1109
+ return lowerCaseName + '#' + CSS.escape(id);
1110
+ }
1111
+ if (classes) {
1112
+ const classList = classes.trim().split(/\s+/g);
1113
+ return (lowerCaseName === 'div' ? '' : lowerCaseName) + '.' + classList.map(cls => CSS.escape(cls)).join('.');
1114
+ }
1115
+ if (this.pseudoIdentifier()) {
1116
+ return `${lowerCaseName}(${this.pseudoIdentifier()})`;
1117
+ }
1118
+ return lowerCaseName;
1119
+ }
1120
+
1121
+ async getAnchorBySpecifier(specifier?: string): Promise<DOMNode|null> {
1122
+ const response = await this.#agent.invoke_getAnchorElement({
1123
+ nodeId: this.id,
1124
+ anchorSpecifier: specifier,
1125
+ });
1126
+
1127
+ if (response.getError()) {
1128
+ return null;
1129
+ }
1130
+
1131
+ return this.domModel().nodeForId(response.nodeId);
1132
+ }
1133
+
1134
+ classNames(): string[] {
1135
+ const classes = this.getAttribute('class');
1136
+ return classes ? classes.split(/\s+/) : [];
1137
+ }
1138
+ }
1139
+
1140
+ export namespace DOMNode {
1141
+ export enum ShadowRootTypes {
1142
+ /* eslint-disable @typescript-eslint/naming-convention -- Used by web_tests. */
1143
+ UserAgent = 'user-agent',
1144
+ Open = 'open',
1145
+ Closed = 'closed',
1146
+ /* eslint-enable @typescript-eslint/naming-convention */
1147
+ }
1148
+ }
1149
+
1150
+ export class DeferredDOMNode {
1151
+ readonly #domModelInternal: DOMModel;
1152
+ readonly #backendNodeIdInternal: Protocol.DOM.BackendNodeId;
1153
+
1154
+ constructor(target: Target, backendNodeId: Protocol.DOM.BackendNodeId) {
1155
+ this.#domModelInternal = (target.model(DOMModel) as DOMModel);
1156
+ this.#backendNodeIdInternal = backendNodeId;
1157
+ }
1158
+
1159
+ resolve(callback: (arg0: DOMNode|null) => void): void {
1160
+ void this.resolvePromise().then(callback);
1161
+ }
1162
+
1163
+ async resolvePromise(): Promise<DOMNode|null> {
1164
+ const nodeIds =
1165
+ await this.#domModelInternal.pushNodesByBackendIdsToFrontend(new Set([this.#backendNodeIdInternal]));
1166
+ return nodeIds?.get(this.#backendNodeIdInternal) || null;
1167
+ }
1168
+
1169
+ backendNodeId(): Protocol.DOM.BackendNodeId {
1170
+ return this.#backendNodeIdInternal;
1171
+ }
1172
+
1173
+ domModel(): DOMModel {
1174
+ return this.#domModelInternal;
1175
+ }
1176
+
1177
+ highlight(): void {
1178
+ this.#domModelInternal.overlayModel().highlightInOverlay({deferredNode: this, selectorList: undefined});
1179
+ }
1180
+ }
1181
+
1182
+ export class DOMNodeShortcut {
1183
+ nodeType: number;
1184
+ nodeName: string;
1185
+ deferredNode: DeferredDOMNode;
1186
+ constructor(target: Target, backendNodeId: Protocol.DOM.BackendNodeId, nodeType: number, nodeName: string) {
1187
+ this.nodeType = nodeType;
1188
+ this.nodeName = nodeName;
1189
+ this.deferredNode = new DeferredDOMNode(target, backendNodeId);
1190
+ }
1191
+ }
1192
+
1193
+ export class DOMDocument extends DOMNode {
1194
+ body: DOMNode|null;
1195
+ documentElement: DOMNode|null;
1196
+ documentURL: Platform.DevToolsPath.UrlString;
1197
+ baseURL: Platform.DevToolsPath.UrlString;
1198
+ constructor(domModel: DOMModel, payload: Protocol.DOM.Node) {
1199
+ super(domModel);
1200
+ this.body = null;
1201
+ this.documentElement = null;
1202
+ this.init(this, false, payload);
1203
+ this.documentURL = (payload.documentURL || '') as Platform.DevToolsPath.UrlString;
1204
+ this.baseURL = (payload.baseURL || '') as Platform.DevToolsPath.UrlString;
1205
+ }
1206
+ }
1207
+
1208
+ export class DOMModel extends SDKModel<EventTypes> {
1209
+ agent: ProtocolProxyApi.DOMApi;
1210
+ idToDOMNode = new Map<Protocol.DOM.NodeId, DOMNode>();
1211
+ #document: DOMDocument|null = null;
1212
+ readonly #attributeLoadNodeIds = new Set<Protocol.DOM.NodeId>();
1213
+ readonly runtimeModelInternal: RuntimeModel;
1214
+ #lastMutationId!: number;
1215
+ #pendingDocumentRequestPromise: Promise<DOMDocument|null>|null = null;
1216
+ #frameOwnerNode?: DOMNode|null;
1217
+ #loadNodeAttributesTimeout?: number;
1218
+ #searchId?: string;
1219
+ constructor(target: Target) {
1220
+ super(target);
1221
+
1222
+ this.agent = target.domAgent();
1223
+
1224
+ target.registerDOMDispatcher(new DOMDispatcher(this));
1225
+ this.runtimeModelInternal = (target.model(RuntimeModel) as RuntimeModel);
1226
+
1227
+ if (!target.suspended()) {
1228
+ void this.agent.invoke_enable({});
1229
+ }
1230
+
1231
+ if (Root.Runtime.experiments.isEnabled('capture-node-creation-stacks')) {
1232
+ void this.agent.invoke_setNodeStackTracesEnabled({enable: true});
1233
+ }
1234
+ }
1235
+
1236
+ runtimeModel(): RuntimeModel {
1237
+ return this.runtimeModelInternal;
1238
+ }
1239
+
1240
+ cssModel(): CSSModel {
1241
+ return this.target().model(CSSModel) as CSSModel;
1242
+ }
1243
+
1244
+ overlayModel(): OverlayModel {
1245
+ return this.target().model(OverlayModel) as OverlayModel;
1246
+ }
1247
+
1248
+ static cancelSearch(): void {
1249
+ for (const domModel of TargetManager.instance().models(DOMModel)) {
1250
+ domModel.cancelSearch();
1251
+ }
1252
+ }
1253
+
1254
+ private scheduleMutationEvent(node: DOMNode): void {
1255
+ if (!this.hasEventListeners(Events.DOMMutated)) {
1256
+ return;
1257
+ }
1258
+
1259
+ this.#lastMutationId = (this.#lastMutationId || 0) + 1;
1260
+ void Promise.resolve().then(callObserve.bind(this, node, this.#lastMutationId));
1261
+
1262
+ function callObserve(this: DOMModel, node: DOMNode, mutationId: number): void {
1263
+ if (!this.hasEventListeners(Events.DOMMutated) || this.#lastMutationId !== mutationId) {
1264
+ return;
1265
+ }
1266
+
1267
+ this.dispatchEventToListeners(Events.DOMMutated, node);
1268
+ }
1269
+ }
1270
+
1271
+ requestDocument(): Promise<DOMDocument|null> {
1272
+ if (this.#document) {
1273
+ return Promise.resolve(this.#document);
1274
+ }
1275
+ if (!this.#pendingDocumentRequestPromise) {
1276
+ this.#pendingDocumentRequestPromise = this.requestDocumentInternal();
1277
+ }
1278
+ return this.#pendingDocumentRequestPromise;
1279
+ }
1280
+
1281
+ async getOwnerNodeForFrame(frameId: Protocol.Page.FrameId): Promise<DeferredDOMNode|null> {
1282
+ // Returns an error if the frameId does not belong to the current target.
1283
+ const response = await this.agent.invoke_getFrameOwner({frameId});
1284
+ if (response.getError()) {
1285
+ return null;
1286
+ }
1287
+ return new DeferredDOMNode(this.target(), response.backendNodeId);
1288
+ }
1289
+
1290
+ private async requestDocumentInternal(): Promise<DOMDocument|null> {
1291
+ const response = await this.agent.invoke_getDocument({});
1292
+ if (response.getError()) {
1293
+ return null;
1294
+ }
1295
+ const {root: documentPayload} = response;
1296
+ this.#pendingDocumentRequestPromise = null;
1297
+
1298
+ if (documentPayload) {
1299
+ this.setDocument(documentPayload);
1300
+ }
1301
+ if (!this.#document) {
1302
+ console.error('No document');
1303
+ return null;
1304
+ }
1305
+
1306
+ const parentModel = this.parentModel();
1307
+ if (parentModel && !this.#frameOwnerNode) {
1308
+ await parentModel.requestDocument();
1309
+ const mainFrame = this.target().model(ResourceTreeModel)?.mainFrame;
1310
+ if (mainFrame) {
1311
+ const response = await parentModel.agent.invoke_getFrameOwner({frameId: mainFrame.id});
1312
+ if (!response.getError() && response.nodeId) {
1313
+ this.#frameOwnerNode = parentModel.nodeForId(response.nodeId);
1314
+ }
1315
+ }
1316
+ }
1317
+
1318
+ // Document could have been cleared by now.
1319
+ if (this.#frameOwnerNode) {
1320
+ const oldDocument = this.#frameOwnerNode.contentDocument();
1321
+ this.#frameOwnerNode.setContentDocument(this.#document);
1322
+ this.#frameOwnerNode.setChildren([]);
1323
+ if (this.#document) {
1324
+ this.#document.parentNode = this.#frameOwnerNode;
1325
+ this.dispatchEventToListeners(Events.NodeInserted, this.#document);
1326
+ } else if (oldDocument) {
1327
+ this.dispatchEventToListeners(Events.NodeRemoved, {node: oldDocument, parent: this.#frameOwnerNode});
1328
+ }
1329
+ }
1330
+ return this.#document;
1331
+ }
1332
+
1333
+ existingDocument(): DOMDocument|null {
1334
+ return this.#document;
1335
+ }
1336
+
1337
+ async pushNodeToFrontend(objectId: Protocol.Runtime.RemoteObjectId): Promise<DOMNode|null> {
1338
+ await this.requestDocument();
1339
+ const {nodeId} = await this.agent.invoke_requestNode({objectId});
1340
+ return this.nodeForId(nodeId);
1341
+ }
1342
+
1343
+ pushNodeByPathToFrontend(path: string): Promise<Protocol.DOM.NodeId|null> {
1344
+ return this.requestDocument()
1345
+ .then(() => this.agent.invoke_pushNodeByPathToFrontend({path}))
1346
+ .then(({nodeId}) => nodeId);
1347
+ }
1348
+
1349
+ async pushNodesByBackendIdsToFrontend(backendNodeIds: Set<Protocol.DOM.BackendNodeId>):
1350
+ Promise<Map<Protocol.DOM.BackendNodeId, DOMNode|null>|null> {
1351
+ await this.requestDocument();
1352
+ const backendNodeIdsArray = [...backendNodeIds];
1353
+ const {nodeIds} = await this.agent.invoke_pushNodesByBackendIdsToFrontend({backendNodeIds: backendNodeIdsArray});
1354
+ if (!nodeIds) {
1355
+ return null;
1356
+ }
1357
+ const map = new Map<Protocol.DOM.BackendNodeId, DOMNode|null>();
1358
+ for (let i = 0; i < nodeIds.length; ++i) {
1359
+ if (nodeIds[i]) {
1360
+ map.set(backendNodeIdsArray[i], this.nodeForId(nodeIds[i]));
1361
+ }
1362
+ }
1363
+ return map;
1364
+ }
1365
+
1366
+ attributeModified(nodeId: Protocol.DOM.NodeId, name: string, value: string): void {
1367
+ const node = this.idToDOMNode.get(nodeId);
1368
+ if (!node) {
1369
+ return;
1370
+ }
1371
+
1372
+ node.setAttributeInternal(name, value);
1373
+ this.dispatchEventToListeners(Events.AttrModified, {node, name});
1374
+ this.scheduleMutationEvent(node);
1375
+ }
1376
+
1377
+ attributeRemoved(nodeId: Protocol.DOM.NodeId, name: string): void {
1378
+ const node = this.idToDOMNode.get(nodeId);
1379
+ if (!node) {
1380
+ return;
1381
+ }
1382
+ node.removeAttributeInternal(name);
1383
+ this.dispatchEventToListeners(Events.AttrRemoved, {node, name});
1384
+ this.scheduleMutationEvent(node);
1385
+ }
1386
+
1387
+ inlineStyleInvalidated(nodeIds: Protocol.DOM.NodeId[]): void {
1388
+ nodeIds.forEach(nodeId => this.#attributeLoadNodeIds.add(nodeId));
1389
+ if (!this.#loadNodeAttributesTimeout) {
1390
+ this.#loadNodeAttributesTimeout = window.setTimeout(this.loadNodeAttributes.bind(this), 20);
1391
+ }
1392
+ }
1393
+
1394
+ private loadNodeAttributes(): void {
1395
+ this.#loadNodeAttributesTimeout = undefined;
1396
+ for (const nodeId of this.#attributeLoadNodeIds) {
1397
+ void this.agent.invoke_getAttributes({nodeId}).then(({attributes}) => {
1398
+ if (!attributes) {
1399
+ // We are calling loadNodeAttributes asynchronously, it is ok if node is not found.
1400
+ return;
1401
+ }
1402
+ const node = this.idToDOMNode.get(nodeId);
1403
+ if (!node) {
1404
+ return;
1405
+ }
1406
+ if (node.setAttributesPayload(attributes)) {
1407
+ this.dispatchEventToListeners(Events.AttrModified, {node, name: 'style'});
1408
+ this.scheduleMutationEvent(node);
1409
+ }
1410
+ });
1411
+ }
1412
+ this.#attributeLoadNodeIds.clear();
1413
+ }
1414
+
1415
+ characterDataModified(nodeId: Protocol.DOM.NodeId, newValue: string): void {
1416
+ const node = this.idToDOMNode.get(nodeId);
1417
+ if (!node) {
1418
+ console.error('nodeId could not be resolved to a node');
1419
+ return;
1420
+ }
1421
+ node.setNodeValueInternal(newValue);
1422
+ this.dispatchEventToListeners(Events.CharacterDataModified, node);
1423
+ this.scheduleMutationEvent(node);
1424
+ }
1425
+
1426
+ nodeForId(nodeId: Protocol.DOM.NodeId|null): DOMNode|null {
1427
+ return nodeId ? this.idToDOMNode.get(nodeId) || null : null;
1428
+ }
1429
+
1430
+ documentUpdated(): void {
1431
+ // If this frame doesn't have a document now,
1432
+ // it means that its document is not requested yet and
1433
+ // it will be requested when needed. (ex: setChildNodes event is received for the frame owner node)
1434
+ // So, we don't need to request the document if we don't
1435
+ // already have a document.
1436
+ const alreadyHasDocument = Boolean(this.#document);
1437
+ this.setDocument(null);
1438
+ // If we have this.#pendingDocumentRequestPromise in flight,
1439
+ // it will contain most recent result.
1440
+ if (this.parentModel() && alreadyHasDocument && !this.#pendingDocumentRequestPromise) {
1441
+ void this.requestDocument();
1442
+ }
1443
+ }
1444
+
1445
+ private setDocument(payload: Protocol.DOM.Node|null): void {
1446
+ this.idToDOMNode = new Map();
1447
+ if (payload && 'nodeId' in payload) {
1448
+ this.#document = new DOMDocument(this, payload);
1449
+ } else {
1450
+ this.#document = null;
1451
+ }
1452
+ DOMModelUndoStack.instance().dispose(this);
1453
+
1454
+ if (!this.parentModel()) {
1455
+ this.dispatchEventToListeners(Events.DocumentUpdated, this);
1456
+ }
1457
+ }
1458
+
1459
+ setDocumentForTest(document: Protocol.DOM.Node|null): void {
1460
+ this.setDocument(document);
1461
+ }
1462
+
1463
+ private setDetachedRoot(payload: Protocol.DOM.Node): void {
1464
+ if (payload.nodeName === '#document') {
1465
+ new DOMDocument(this, payload);
1466
+ } else {
1467
+ DOMNode.create(this, null, false, payload);
1468
+ }
1469
+ }
1470
+
1471
+ setChildNodes(parentId: Protocol.DOM.NodeId, payloads: Protocol.DOM.Node[]): void {
1472
+ if (!parentId && payloads.length) {
1473
+ this.setDetachedRoot(payloads[0]);
1474
+ return;
1475
+ }
1476
+
1477
+ const parent = this.idToDOMNode.get(parentId);
1478
+ parent?.setChildrenPayload(payloads);
1479
+ }
1480
+
1481
+ childNodeCountUpdated(nodeId: Protocol.DOM.NodeId, newValue: number): void {
1482
+ const node = this.idToDOMNode.get(nodeId);
1483
+ if (!node) {
1484
+ console.error('nodeId could not be resolved to a node');
1485
+ return;
1486
+ }
1487
+ node.setChildNodeCount(newValue);
1488
+ this.dispatchEventToListeners(Events.ChildNodeCountUpdated, node);
1489
+ this.scheduleMutationEvent(node);
1490
+ }
1491
+
1492
+ childNodeInserted(parentId: Protocol.DOM.NodeId, prevId: Protocol.DOM.NodeId, payload: Protocol.DOM.Node): void {
1493
+ const parent = this.idToDOMNode.get(parentId);
1494
+ const prev = this.idToDOMNode.get(prevId);
1495
+ if (!parent) {
1496
+ console.error('parentId could not be resolved to a node');
1497
+ return;
1498
+ }
1499
+ const node = parent.insertChild(prev, payload);
1500
+ this.idToDOMNode.set(node.id, node);
1501
+ this.dispatchEventToListeners(Events.NodeInserted, node);
1502
+ this.scheduleMutationEvent(node);
1503
+ }
1504
+
1505
+ childNodeRemoved(parentId: Protocol.DOM.NodeId, nodeId: Protocol.DOM.NodeId): void {
1506
+ const parent = this.idToDOMNode.get(parentId);
1507
+ const node = this.idToDOMNode.get(nodeId);
1508
+ if (!parent || !node) {
1509
+ console.error('parentId or nodeId could not be resolved to a node');
1510
+ return;
1511
+ }
1512
+ parent.removeChild(node);
1513
+ this.unbind(node);
1514
+ this.dispatchEventToListeners(Events.NodeRemoved, {node, parent});
1515
+ this.scheduleMutationEvent(node);
1516
+ }
1517
+
1518
+ shadowRootPushed(hostId: Protocol.DOM.NodeId, root: Protocol.DOM.Node): void {
1519
+ const host = this.idToDOMNode.get(hostId);
1520
+ if (!host) {
1521
+ return;
1522
+ }
1523
+ const node = DOMNode.create(this, host.ownerDocument, true, root);
1524
+ node.parentNode = host;
1525
+ this.idToDOMNode.set(node.id, node);
1526
+ host.shadowRootsInternal.unshift(node);
1527
+ this.dispatchEventToListeners(Events.NodeInserted, node);
1528
+ this.scheduleMutationEvent(node);
1529
+ }
1530
+
1531
+ shadowRootPopped(hostId: Protocol.DOM.NodeId, rootId: Protocol.DOM.NodeId): void {
1532
+ const host = this.idToDOMNode.get(hostId);
1533
+ if (!host) {
1534
+ return;
1535
+ }
1536
+ const root = this.idToDOMNode.get(rootId);
1537
+ if (!root) {
1538
+ return;
1539
+ }
1540
+ host.removeChild(root);
1541
+ this.unbind(root);
1542
+ this.dispatchEventToListeners(Events.NodeRemoved, {node: root, parent: host});
1543
+ this.scheduleMutationEvent(root);
1544
+ }
1545
+
1546
+ pseudoElementAdded(parentId: Protocol.DOM.NodeId, pseudoElement: Protocol.DOM.Node): void {
1547
+ const parent = this.idToDOMNode.get(parentId);
1548
+ if (!parent) {
1549
+ return;
1550
+ }
1551
+ const node = DOMNode.create(this, parent.ownerDocument, false, pseudoElement);
1552
+ node.parentNode = parent;
1553
+ this.idToDOMNode.set(node.id, node);
1554
+ const pseudoType = node.pseudoType();
1555
+ if (!pseudoType) {
1556
+ throw new Error('DOMModel._pseudoElementAdded expects pseudoType to be defined.');
1557
+ }
1558
+ const currentPseudoElements = parent.pseudoElements().get(pseudoType);
1559
+ if (currentPseudoElements && currentPseudoElements.length > 0) {
1560
+ if (!(pseudoType.startsWith('view-transition') || pseudoType.startsWith('scroll-') || pseudoType === 'column')) {
1561
+ throw new Error(
1562
+ 'DOMModel.pseudoElementAdded expects parent to not already have this pseudo type added; only view-transition* and scrolling pseudo elements can coexist under the same parent.' +
1563
+ ` ${currentPseudoElements.length} elements of type ${pseudoType} already exist on parent.`);
1564
+ }
1565
+ currentPseudoElements.push(node);
1566
+ } else {
1567
+ parent.pseudoElements().set(pseudoType, [node]);
1568
+ }
1569
+ this.dispatchEventToListeners(Events.NodeInserted, node);
1570
+ this.scheduleMutationEvent(node);
1571
+ }
1572
+
1573
+ scrollableFlagUpdated(nodeId: Protocol.DOM.NodeId, isScrollable: boolean): void {
1574
+ const node = this.nodeForId(nodeId);
1575
+ if (!node || node.isScrollable() === isScrollable) {
1576
+ return;
1577
+ }
1578
+ node.setIsScrollable(isScrollable);
1579
+ this.dispatchEventToListeners(Events.ScrollableFlagUpdated, {node});
1580
+ }
1581
+
1582
+ affectedByStartingStylesFlagUpdated(nodeId: Protocol.DOM.NodeId, affectedByStartingStyles: boolean): void {
1583
+ const node = this.nodeForId(nodeId);
1584
+ if (!node || node.affectedByStartingStyles() === affectedByStartingStyles) {
1585
+ return;
1586
+ }
1587
+ node.setAffectedByStartingStyles(affectedByStartingStyles);
1588
+ this.dispatchEventToListeners(Events.AffectedByStartingStylesFlagUpdated, {node});
1589
+ }
1590
+
1591
+ topLayerElementsUpdated(): void {
1592
+ this.dispatchEventToListeners(Events.TopLayerElementsChanged);
1593
+ }
1594
+
1595
+ pseudoElementRemoved(parentId: Protocol.DOM.NodeId, pseudoElementId: Protocol.DOM.NodeId): void {
1596
+ const parent = this.idToDOMNode.get(parentId);
1597
+ if (!parent) {
1598
+ return;
1599
+ }
1600
+ const pseudoElement = this.idToDOMNode.get(pseudoElementId);
1601
+ if (!pseudoElement) {
1602
+ return;
1603
+ }
1604
+ parent.removeChild(pseudoElement);
1605
+ this.unbind(pseudoElement);
1606
+ this.dispatchEventToListeners(Events.NodeRemoved, {node: pseudoElement, parent});
1607
+ this.scheduleMutationEvent(pseudoElement);
1608
+ }
1609
+
1610
+ distributedNodesUpdated(insertionPointId: Protocol.DOM.NodeId, distributedNodes: Protocol.DOM.BackendNode[]): void {
1611
+ const insertionPoint = this.idToDOMNode.get(insertionPointId);
1612
+ if (!insertionPoint) {
1613
+ return;
1614
+ }
1615
+ insertionPoint.setDistributedNodePayloads(distributedNodes);
1616
+ this.dispatchEventToListeners(Events.DistributedNodesChanged, insertionPoint);
1617
+ this.scheduleMutationEvent(insertionPoint);
1618
+ }
1619
+
1620
+ private unbind(node: DOMNode): void {
1621
+ this.idToDOMNode.delete(node.id);
1622
+ const children = node.children();
1623
+ for (let i = 0; children && i < children.length; ++i) {
1624
+ this.unbind(children[i]);
1625
+ }
1626
+ for (let i = 0; i < node.shadowRootsInternal.length; ++i) {
1627
+ this.unbind(node.shadowRootsInternal[i]);
1628
+ }
1629
+ const pseudoElements = node.pseudoElements();
1630
+ for (const value of pseudoElements.values()) {
1631
+ for (const pseudoElement of value) {
1632
+ this.unbind(pseudoElement);
1633
+ }
1634
+ }
1635
+ const templateContent = node.templateContent();
1636
+ if (templateContent) {
1637
+ this.unbind(templateContent);
1638
+ }
1639
+ }
1640
+
1641
+ async getNodesByStyle(
1642
+ computedStyles: Array<{
1643
+ name: string,
1644
+ value: string,
1645
+ }>,
1646
+ pierce = false): Promise<Protocol.DOM.NodeId[]> {
1647
+ await this.requestDocument();
1648
+ if (!this.#document) {
1649
+ throw new Error('DOMModel.getNodesByStyle expects to have a document.');
1650
+ }
1651
+ const response =
1652
+ await this.agent.invoke_getNodesForSubtreeByStyle({nodeId: this.#document.id, computedStyles, pierce});
1653
+ if (response.getError()) {
1654
+ throw new Error(response.getError());
1655
+ }
1656
+ return response.nodeIds;
1657
+ }
1658
+
1659
+ async performSearch(query: string, includeUserAgentShadowDOM: boolean): Promise<number> {
1660
+ const response = await this.agent.invoke_performSearch({query, includeUserAgentShadowDOM});
1661
+ if (!response.getError()) {
1662
+ this.#searchId = response.searchId;
1663
+ }
1664
+ return response.getError() ? 0 : response.resultCount;
1665
+ }
1666
+
1667
+ async searchResult(index: number): Promise<DOMNode|null> {
1668
+ if (!this.#searchId) {
1669
+ return null;
1670
+ }
1671
+ const {nodeIds} =
1672
+ await this.agent.invoke_getSearchResults({searchId: this.#searchId, fromIndex: index, toIndex: index + 1});
1673
+ return nodeIds && nodeIds.length === 1 ? this.nodeForId(nodeIds[0]) : null;
1674
+ }
1675
+
1676
+ private cancelSearch(): void {
1677
+ if (!this.#searchId) {
1678
+ return;
1679
+ }
1680
+ void this.agent.invoke_discardSearchResults({searchId: this.#searchId});
1681
+ this.#searchId = undefined;
1682
+ }
1683
+
1684
+ classNamesPromise(nodeId: Protocol.DOM.NodeId): Promise<string[]> {
1685
+ return this.agent.invoke_collectClassNamesFromSubtree({nodeId}).then(({classNames}) => classNames || []);
1686
+ }
1687
+
1688
+ querySelector(nodeId: Protocol.DOM.NodeId, selector: string): Promise<Protocol.DOM.NodeId|null> {
1689
+ return this.agent.invoke_querySelector({nodeId, selector}).then(({nodeId}) => nodeId);
1690
+ }
1691
+
1692
+ querySelectorAll(nodeId: Protocol.DOM.NodeId, selector: string): Promise<Protocol.DOM.NodeId[]|null> {
1693
+ return this.agent.invoke_querySelectorAll({nodeId, selector}).then(({nodeIds}) => nodeIds);
1694
+ }
1695
+
1696
+ getTopLayerElements(): Promise<Protocol.DOM.NodeId[]|null> {
1697
+ return this.agent.invoke_getTopLayerElements().then(({nodeIds}) => nodeIds);
1698
+ }
1699
+
1700
+ getDetachedDOMNodes(): Promise<Protocol.DOM.DetachedElementInfo[]|null> {
1701
+ return this.agent.invoke_getDetachedDomNodes().then(({detachedNodes}) => detachedNodes);
1702
+ }
1703
+
1704
+ getElementByRelation(nodeId: Protocol.DOM.NodeId, relation: Protocol.DOM.GetElementByRelationRequestRelation):
1705
+ Promise<Protocol.DOM.NodeId|null> {
1706
+ return this.agent.invoke_getElementByRelation({nodeId, relation}).then(({nodeId}) => nodeId);
1707
+ }
1708
+
1709
+ markUndoableState(minorChange?: boolean): void {
1710
+ void DOMModelUndoStack.instance().markUndoableState(this, minorChange || false);
1711
+ }
1712
+
1713
+ async nodeForLocation(x: number, y: number, includeUserAgentShadowDOM: boolean): Promise<DOMNode|null> {
1714
+ const response = await this.agent.invoke_getNodeForLocation({x, y, includeUserAgentShadowDOM});
1715
+ if (response.getError() || !response.nodeId) {
1716
+ return null;
1717
+ }
1718
+ return this.nodeForId(response.nodeId);
1719
+ }
1720
+
1721
+ async getContainerForNode(
1722
+ nodeId: Protocol.DOM.NodeId, containerName?: string, physicalAxes?: Protocol.DOM.PhysicalAxes,
1723
+ logicalAxes?: Protocol.DOM.LogicalAxes, queriesScrollState?: boolean,
1724
+ queriesAnchored?: boolean): Promise<DOMNode|null> {
1725
+ const {nodeId: containerNodeId} = await this.agent.invoke_getContainerForNode(
1726
+ {nodeId, containerName, physicalAxes, logicalAxes, queriesScrollState, queriesAnchored});
1727
+ if (!containerNodeId) {
1728
+ return null;
1729
+ }
1730
+ return this.nodeForId(containerNodeId);
1731
+ }
1732
+
1733
+ pushObjectAsNodeToFrontend(object: RemoteObject): Promise<DOMNode|null> {
1734
+ return object.isNode() && object.objectId ? this.pushNodeToFrontend(object.objectId) : Promise.resolve(null);
1735
+ }
1736
+
1737
+ override suspendModel(): Promise<void> {
1738
+ return this.agent.invoke_disable().then(() => this.setDocument(null));
1739
+ }
1740
+
1741
+ override async resumeModel(): Promise<void> {
1742
+ await this.agent.invoke_enable({});
1743
+ }
1744
+
1745
+ override dispose(): void {
1746
+ DOMModelUndoStack.instance().dispose(this);
1747
+ }
1748
+
1749
+ parentModel(): DOMModel|null {
1750
+ const parentTarget = this.target().parentTarget();
1751
+ return parentTarget ? parentTarget.model(DOMModel) : null;
1752
+ }
1753
+
1754
+ getAgent(): ProtocolProxyApi.DOMApi {
1755
+ return this.agent;
1756
+ }
1757
+
1758
+ registerNode(node: DOMNode): void {
1759
+ this.idToDOMNode.set(node.id, node);
1760
+ }
1761
+ }
1762
+
1763
+ export enum Events {
1764
+ /* eslint-disable @typescript-eslint/naming-convention -- Used by web_tests. */
1765
+ AttrModified = 'AttrModified',
1766
+ AttrRemoved = 'AttrRemoved',
1767
+ CharacterDataModified = 'CharacterDataModified',
1768
+ DOMMutated = 'DOMMutated',
1769
+ NodeInserted = 'NodeInserted',
1770
+ NodeRemoved = 'NodeRemoved',
1771
+ DocumentUpdated = 'DocumentUpdated',
1772
+ ChildNodeCountUpdated = 'ChildNodeCountUpdated',
1773
+ DistributedNodesChanged = 'DistributedNodesChanged',
1774
+ MarkersChanged = 'MarkersChanged',
1775
+ TopLayerElementsChanged = 'TopLayerElementsChanged',
1776
+ ScrollableFlagUpdated = 'ScrollableFlagUpdated',
1777
+ AffectedByStartingStylesFlagUpdated = 'AffectedByStartingStylesFlagUpdated',
1778
+ /* eslint-enable @typescript-eslint/naming-convention */
1779
+ }
1780
+
1781
+ export interface EventTypes {
1782
+ [Events.AttrModified]: {node: DOMNode, name: string};
1783
+ [Events.AttrRemoved]: {node: DOMNode, name: string};
1784
+ [Events.CharacterDataModified]: DOMNode;
1785
+ [Events.DOMMutated]: DOMNode;
1786
+ [Events.NodeInserted]: DOMNode;
1787
+ [Events.NodeRemoved]: {node: DOMNode, parent: DOMNode};
1788
+ [Events.DocumentUpdated]: DOMModel;
1789
+ [Events.ChildNodeCountUpdated]: DOMNode;
1790
+ [Events.DistributedNodesChanged]: DOMNode;
1791
+ [Events.MarkersChanged]: DOMNode;
1792
+ [Events.TopLayerElementsChanged]: void;
1793
+ [Events.ScrollableFlagUpdated]: {node: DOMNode};
1794
+ [Events.AffectedByStartingStylesFlagUpdated]: {node: DOMNode};
1795
+ }
1796
+
1797
+ class DOMDispatcher implements ProtocolProxyApi.DOMDispatcher {
1798
+ readonly #domModel: DOMModel;
1799
+ constructor(domModel: DOMModel) {
1800
+ this.#domModel = domModel;
1801
+ }
1802
+
1803
+ documentUpdated(): void {
1804
+ this.#domModel.documentUpdated();
1805
+ }
1806
+
1807
+ attributeModified({nodeId, name, value}: Protocol.DOM.AttributeModifiedEvent): void {
1808
+ this.#domModel.attributeModified(nodeId, name, value);
1809
+ }
1810
+
1811
+ attributeRemoved({nodeId, name}: Protocol.DOM.AttributeRemovedEvent): void {
1812
+ this.#domModel.attributeRemoved(nodeId, name);
1813
+ }
1814
+
1815
+ inlineStyleInvalidated({nodeIds}: Protocol.DOM.InlineStyleInvalidatedEvent): void {
1816
+ this.#domModel.inlineStyleInvalidated(nodeIds);
1817
+ }
1818
+
1819
+ characterDataModified({nodeId, characterData}: Protocol.DOM.CharacterDataModifiedEvent): void {
1820
+ this.#domModel.characterDataModified(nodeId, characterData);
1821
+ }
1822
+
1823
+ setChildNodes({parentId, nodes}: Protocol.DOM.SetChildNodesEvent): void {
1824
+ this.#domModel.setChildNodes(parentId, nodes);
1825
+ }
1826
+
1827
+ childNodeCountUpdated({nodeId, childNodeCount}: Protocol.DOM.ChildNodeCountUpdatedEvent): void {
1828
+ this.#domModel.childNodeCountUpdated(nodeId, childNodeCount);
1829
+ }
1830
+
1831
+ childNodeInserted({parentNodeId, previousNodeId, node}: Protocol.DOM.ChildNodeInsertedEvent): void {
1832
+ this.#domModel.childNodeInserted(parentNodeId, previousNodeId, node);
1833
+ }
1834
+
1835
+ childNodeRemoved({parentNodeId, nodeId}: Protocol.DOM.ChildNodeRemovedEvent): void {
1836
+ this.#domModel.childNodeRemoved(parentNodeId, nodeId);
1837
+ }
1838
+
1839
+ shadowRootPushed({hostId, root}: Protocol.DOM.ShadowRootPushedEvent): void {
1840
+ this.#domModel.shadowRootPushed(hostId, root);
1841
+ }
1842
+
1843
+ shadowRootPopped({hostId, rootId}: Protocol.DOM.ShadowRootPoppedEvent): void {
1844
+ this.#domModel.shadowRootPopped(hostId, rootId);
1845
+ }
1846
+
1847
+ pseudoElementAdded({parentId, pseudoElement}: Protocol.DOM.PseudoElementAddedEvent): void {
1848
+ this.#domModel.pseudoElementAdded(parentId, pseudoElement);
1849
+ }
1850
+
1851
+ pseudoElementRemoved({parentId, pseudoElementId}: Protocol.DOM.PseudoElementRemovedEvent): void {
1852
+ this.#domModel.pseudoElementRemoved(parentId, pseudoElementId);
1853
+ }
1854
+
1855
+ distributedNodesUpdated({insertionPointId, distributedNodes}: Protocol.DOM.DistributedNodesUpdatedEvent): void {
1856
+ this.#domModel.distributedNodesUpdated(insertionPointId, distributedNodes);
1857
+ }
1858
+
1859
+ topLayerElementsUpdated(): void {
1860
+ this.#domModel.topLayerElementsUpdated();
1861
+ }
1862
+
1863
+ scrollableFlagUpdated({nodeId, isScrollable}: Protocol.DOM.ScrollableFlagUpdatedEvent): void {
1864
+ this.#domModel.scrollableFlagUpdated(nodeId, isScrollable);
1865
+ }
1866
+
1867
+ affectedByStartingStylesFlagUpdated({nodeId, affectedByStartingStyles}:
1868
+ Protocol.DOM.AffectedByStartingStylesFlagUpdatedEvent): void {
1869
+ this.#domModel.affectedByStartingStylesFlagUpdated(nodeId, affectedByStartingStyles);
1870
+ }
1871
+ }
1872
+
1873
+ let domModelUndoStackInstance: DOMModelUndoStack|null = null;
1874
+
1875
+ export class DOMModelUndoStack {
1876
+ #stack: DOMModel[];
1877
+ #index: number;
1878
+ #lastModelWithMinorChange: DOMModel|null;
1879
+ constructor() {
1880
+ this.#stack = [];
1881
+ this.#index = 0;
1882
+ this.#lastModelWithMinorChange = null;
1883
+ }
1884
+
1885
+ static instance(opts: {
1886
+ forceNew: boolean|null,
1887
+ } = {forceNew: null}): DOMModelUndoStack {
1888
+ const {forceNew} = opts;
1889
+ if (!domModelUndoStackInstance || forceNew) {
1890
+ domModelUndoStackInstance = new DOMModelUndoStack();
1891
+ }
1892
+
1893
+ return domModelUndoStackInstance;
1894
+ }
1895
+
1896
+ async markUndoableState(model: DOMModel, minorChange: boolean): Promise<void> {
1897
+ // Both minor and major changes get into the #stack, but minor updates are coalesced.
1898
+ // Commit major undoable state in the old model upon model switch.
1899
+ if (this.#lastModelWithMinorChange && model !== this.#lastModelWithMinorChange) {
1900
+ this.#lastModelWithMinorChange.markUndoableState();
1901
+ this.#lastModelWithMinorChange = null;
1902
+ }
1903
+
1904
+ // Previous minor change is already in the #stack.
1905
+ if (minorChange && this.#lastModelWithMinorChange === model) {
1906
+ return;
1907
+ }
1908
+
1909
+ this.#stack = this.#stack.slice(0, this.#index);
1910
+ this.#stack.push(model);
1911
+ this.#index = this.#stack.length;
1912
+
1913
+ // Delay marking as major undoable states in case of minor operations until the
1914
+ // major or model switch.
1915
+ if (minorChange) {
1916
+ this.#lastModelWithMinorChange = model;
1917
+ } else {
1918
+ await model.getAgent().invoke_markUndoableState();
1919
+ this.#lastModelWithMinorChange = null;
1920
+ }
1921
+ }
1922
+
1923
+ async undo(): Promise<void> {
1924
+ if (this.#index === 0) {
1925
+ return await Promise.resolve();
1926
+ }
1927
+ --this.#index;
1928
+ this.#lastModelWithMinorChange = null;
1929
+ await this.#stack[this.#index].getAgent().invoke_undo();
1930
+ }
1931
+
1932
+ async redo(): Promise<void> {
1933
+ if (this.#index >= this.#stack.length) {
1934
+ return await Promise.resolve();
1935
+ }
1936
+ ++this.#index;
1937
+ this.#lastModelWithMinorChange = null;
1938
+ await this.#stack[this.#index - 1].getAgent().invoke_redo();
1939
+ }
1940
+
1941
+ dispose(model: DOMModel): void {
1942
+ let shift = 0;
1943
+ for (let i = 0; i < this.#index; ++i) {
1944
+ if (this.#stack[i] === model) {
1945
+ ++shift;
1946
+ }
1947
+ }
1948
+ Platform.ArrayUtilities.removeElement(this.#stack, model);
1949
+ this.#index -= shift;
1950
+ if (this.#lastModelWithMinorChange === model) {
1951
+ this.#lastModelWithMinorChange = null;
1952
+ }
1953
+ }
1954
+ }
1955
+
1956
+ SDKModel.register(DOMModel, {capabilities: Capability.DOM, autostart: true});
1957
+ export interface Attribute {
1958
+ name: string;
1959
+ value: string;
1960
+ _node: DOMNode;
1961
+ }