browser-debugger-cli 0.8.0 → 0.10.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 (304) hide show
  1. package/README.md +7 -1
  2. package/dist/cdp/schema.d.ts +4 -1
  3. package/dist/cdp/schema.js +48 -7
  4. package/dist/commands/cdp.js +3 -2
  5. package/dist/commands/cleanup.d.ts +11 -0
  6. package/dist/commands/cleanup.js +161 -57
  7. package/dist/commands/console.d.ts +20 -1
  8. package/dist/commands/console.js +57 -17
  9. package/dist/commands/details.js +3 -2
  10. package/dist/commands/dom/DomElementResolver.d.ts +10 -3
  11. package/dist/commands/dom/DomElementResolver.js +35 -17
  12. package/dist/commands/dom/a11y.d.ts +10 -0
  13. package/dist/commands/dom/a11y.js +29 -6
  14. package/dist/commands/dom/eval.d.ts +3 -1
  15. package/dist/commands/dom/eval.js +29 -4
  16. package/dist/commands/dom/form.js +16 -62
  17. package/dist/commands/dom/formInteraction.js +189 -119
  18. package/dist/commands/dom/formSummary.d.ts +49 -0
  19. package/dist/commands/dom/formSummary.js +180 -0
  20. package/dist/commands/dom/frames.d.ts +2 -1
  21. package/dist/commands/dom/frames.js +17 -2
  22. package/dist/commands/dom/get.d.ts +6 -5
  23. package/dist/commands/dom/get.js +92 -82
  24. package/dist/commands/dom/helpers/index.d.ts +1 -1
  25. package/dist/commands/dom/helpers/index.js +1 -1
  26. package/dist/commands/dom/helpers/keyAttributes.d.ts +20 -0
  27. package/dist/commands/dom/helpers/keyAttributes.js +54 -0
  28. package/dist/commands/dom/helpers/query.d.ts +44 -17
  29. package/dist/commands/dom/helpers/query.js +300 -106
  30. package/dist/commands/dom/helpers/runElementCommand.d.ts +10 -2
  31. package/dist/commands/dom/helpers/runElementCommand.js +98 -30
  32. package/dist/commands/dom/helpers/screenshot.d.ts +4 -1
  33. package/dist/commands/dom/helpers/screenshot.js +239 -51
  34. package/dist/commands/dom/index.d.ts +4 -1
  35. package/dist/commands/dom/index.js +22 -7
  36. package/dist/commands/dom/inspect.d.ts +15 -0
  37. package/dist/commands/dom/inspect.js +82 -0
  38. package/dist/commands/dom/layout.d.ts +14 -0
  39. package/dist/commands/dom/layout.js +54 -0
  40. package/dist/commands/dom/listeners.d.ts +5 -1
  41. package/dist/commands/dom/listeners.js +15 -5
  42. package/dist/commands/dom/query.js +2 -3
  43. package/dist/commands/dom/screenshot.d.ts +12 -2
  44. package/dist/commands/dom/screenshot.js +27 -3
  45. package/dist/commands/dom/semanticUtils.d.ts +16 -10
  46. package/dist/commands/dom/semanticUtils.js +53 -16
  47. package/dist/commands/dom/wait.d.ts +13 -0
  48. package/dist/commands/dom/wait.js +83 -0
  49. package/dist/commands/helpJson.js +2 -2
  50. package/dist/commands/network/list.js +17 -13
  51. package/dist/commands/optionBehaviors.js +154 -21
  52. package/dist/commands/page.d.ts +3 -2
  53. package/dist/commands/page.js +100 -5
  54. package/dist/commands/peek.js +4 -11
  55. package/dist/commands/sessions.d.ts +8 -0
  56. package/dist/commands/sessions.js +19 -0
  57. package/dist/commands/shared/CommandRunner.js +4 -4
  58. package/dist/commands/shared/commonOptions.d.ts +4 -0
  59. package/dist/commands/shared/commonOptions.js +9 -0
  60. package/dist/commands/shared/dataFetcher.js +2 -2
  61. package/dist/commands/shared/followMode.d.ts +21 -1
  62. package/dist/commands/shared/followMode.js +29 -2
  63. package/dist/commands/shared/handleValidationError.d.ts +2 -2
  64. package/dist/commands/shared/handleValidationError.js +12 -3
  65. package/dist/commands/shared/optionTypes.d.ts +61 -5
  66. package/dist/commands/shared/startHelpers.d.ts +66 -0
  67. package/dist/commands/shared/startHelpers.js +103 -13
  68. package/dist/commands/shared/validation.d.ts +14 -2
  69. package/dist/commands/shared/validation.js +20 -3
  70. package/dist/commands/start.d.ts +63 -0
  71. package/dist/commands/start.js +115 -15
  72. package/dist/commands/status.js +29 -7
  73. package/dist/commands/stop.js +7 -6
  74. package/dist/commands/tail.js +4 -11
  75. package/dist/commands/types.d.ts +2 -0
  76. package/dist/commands.js +2 -0
  77. package/dist/connection/chromeIdentity.d.ts +65 -0
  78. package/dist/connection/chromeIdentity.js +143 -0
  79. package/dist/connection/launcher/profilePreferences.d.ts +47 -0
  80. package/dist/connection/launcher/profilePreferences.js +151 -0
  81. package/dist/connection/launcher.d.ts +21 -2
  82. package/dist/connection/launcher.js +42 -16
  83. package/dist/connection/portReservation.d.ts +14 -4
  84. package/dist/connection/portReservation.js +21 -6
  85. package/dist/connection/startupExit.d.ts +8 -0
  86. package/dist/connection/startupExit.js +15 -6
  87. package/dist/constants.d.ts +6 -2
  88. package/dist/constants.js +9 -2
  89. package/dist/daemon/SessionController.js +23 -7
  90. package/dist/daemon/errors.d.ts +1 -1
  91. package/dist/daemon/errors.js +1 -1
  92. package/dist/daemon/launcher.d.ts +10 -2
  93. package/dist/daemon/launcher.js +8 -7
  94. package/dist/daemon/server/SocketServer.js +1 -2
  95. package/dist/daemon/session/Session.d.ts +20 -0
  96. package/dist/daemon/session/Session.js +80 -9
  97. package/dist/daemon/session/chromeConnection.d.ts +9 -0
  98. package/dist/daemon/session/chromeConnection.js +45 -8
  99. package/dist/daemon/session/commandRegistry.d.ts +14 -1
  100. package/dist/daemon/session/commandRegistry.js +113 -67
  101. package/dist/daemon/session/interactions.d.ts +48 -9
  102. package/dist/daemon/session/interactions.js +46 -9
  103. package/dist/daemon/session/triggeredRequests.d.ts +67 -0
  104. package/dist/daemon/session/triggeredRequests.js +157 -0
  105. package/dist/daemon/session/types.d.ts +5 -1
  106. package/dist/daemon.js +10630 -3601
  107. package/dist/errors/messages.d.ts +456 -24
  108. package/dist/errors/messages.js +862 -67
  109. package/dist/index.js +6915 -3401
  110. package/dist/ipc/client.d.ts +21 -1
  111. package/dist/ipc/client.js +35 -3
  112. package/dist/ipc/protocol/commands.d.ts +145 -5
  113. package/dist/ipc/protocol/commands.js +4 -0
  114. package/dist/ipc/protocol/domTypes.d.ts +291 -7
  115. package/dist/ipc/protocol/inspectTypes.d.ts +388 -0
  116. package/dist/ipc/protocol/inspectTypes.js +10 -0
  117. package/dist/ipc/session/lifecycle.d.ts +8 -1
  118. package/dist/ipc/session/queries.d.ts +5 -1
  119. package/dist/ipc/session/types.d.ts +5 -0
  120. package/dist/ipc/transport/index.d.ts +2 -1
  121. package/dist/ipc/transport/index.js +2 -2
  122. package/dist/runtime/dom/actionEffects.d.ts +185 -0
  123. package/dist/runtime/dom/actionEffects.js +402 -0
  124. package/dist/runtime/dom/actionEffectsScripts.d.ts +90 -0
  125. package/dist/runtime/dom/actionEffectsScripts.js +426 -0
  126. package/dist/runtime/dom/elementGeometry.d.ts +170 -0
  127. package/dist/runtime/dom/elementGeometry.js +553 -0
  128. package/dist/runtime/dom/elementInfo.d.ts +103 -0
  129. package/dist/runtime/dom/elementInfo.js +256 -0
  130. package/dist/runtime/dom/evalHelpers.d.ts +51 -6
  131. package/dist/runtime/dom/evalHelpers.js +136 -26
  132. package/dist/runtime/dom/eventListeners.d.ts +2 -1
  133. package/dist/runtime/dom/eventListeners.js +184 -47
  134. package/dist/runtime/dom/formDiscovery.d.ts +1 -1
  135. package/dist/runtime/dom/formDiscovery.js +116 -16
  136. package/dist/runtime/dom/formFillHelpers/fill.d.ts +9 -0
  137. package/dist/runtime/dom/formFillHelpers/fill.js +178 -14
  138. package/dist/runtime/dom/formFillHelpers/index.d.ts +2 -2
  139. package/dist/runtime/dom/formFillHelpers/index.js +2 -2
  140. package/dist/runtime/dom/formFillHelpers/pressKey.js +14 -3
  141. package/dist/runtime/dom/formFillHelpers/scroll.d.ts +3 -0
  142. package/dist/runtime/dom/formFillHelpers/scroll.js +60 -18
  143. package/dist/runtime/dom/formFillHelpers/shared.d.ts +17 -0
  144. package/dist/runtime/dom/formFillHelpers/shared.js +25 -1
  145. package/dist/runtime/dom/formFillHelpers/stability.d.ts +20 -6
  146. package/dist/runtime/dom/formFillHelpers/stability.js +50 -19
  147. package/dist/runtime/dom/formSubmitHelpers.d.ts +3 -0
  148. package/dist/runtime/dom/formSubmitHelpers.js +89 -15
  149. package/dist/runtime/dom/frameLayout.d.ts +60 -0
  150. package/dist/runtime/dom/frameLayout.js +140 -0
  151. package/dist/runtime/dom/frameOrigin.d.ts +50 -0
  152. package/dist/runtime/dom/frameOrigin.js +62 -0
  153. package/dist/runtime/dom/frameScopedConnection.d.ts +92 -0
  154. package/dist/runtime/dom/frameScopedConnection.js +252 -0
  155. package/dist/runtime/dom/frameSelection.d.ts +12 -1
  156. package/dist/runtime/dom/frameSelection.js +22 -3
  157. package/dist/runtime/dom/frames.d.ts +61 -5
  158. package/dist/runtime/dom/frames.js +329 -75
  159. package/dist/runtime/dom/inspect.d.ts +28 -0
  160. package/dist/runtime/dom/inspect.js +557 -0
  161. package/dist/runtime/dom/inspectAllStyles.d.ts +62 -0
  162. package/dist/runtime/dom/inspectAllStyles.js +385 -0
  163. package/dist/runtime/dom/inspectCascade.d.ts +94 -0
  164. package/dist/runtime/dom/inspectCascade.js +371 -0
  165. package/dist/runtime/dom/inspectCascadeModel.d.ts +39 -0
  166. package/dist/runtime/dom/inspectCascadeModel.js +232 -0
  167. package/dist/runtime/dom/inspectHints.d.ts +62 -0
  168. package/dist/runtime/dom/inspectHints.js +305 -0
  169. package/dist/runtime/dom/inspectLayoutModel.d.ts +87 -0
  170. package/dist/runtime/dom/inspectLayoutModel.js +346 -0
  171. package/dist/runtime/dom/inspectModel.d.ts +74 -0
  172. package/dist/runtime/dom/inspectModel.js +184 -0
  173. package/dist/runtime/dom/inspectPaintModel.d.ts +157 -0
  174. package/dist/runtime/dom/inspectPaintModel.js +461 -0
  175. package/dist/runtime/dom/inspectRules.d.ts +37 -0
  176. package/dist/runtime/dom/inspectRules.js +101 -0
  177. package/dist/runtime/dom/inspectScripts.d.ts +132 -0
  178. package/dist/runtime/dom/inspectScripts.js +263 -0
  179. package/dist/runtime/dom/inspectTree.d.ts +40 -0
  180. package/dist/runtime/dom/inspectTree.js +134 -0
  181. package/dist/runtime/dom/inspectVariables.d.ts +33 -0
  182. package/dist/runtime/dom/inspectVariables.js +94 -0
  183. package/dist/runtime/dom/inspectWhyModel.d.ts +20 -0
  184. package/dist/runtime/dom/inspectWhyModel.js +134 -0
  185. package/dist/runtime/dom/layout.d.ts +71 -0
  186. package/dist/runtime/dom/layout.js +340 -0
  187. package/dist/runtime/dom/listenerPageScripts.d.ts +72 -0
  188. package/dist/runtime/dom/listenerPageScripts.js +365 -0
  189. package/dist/runtime/dom/listenerSummary.d.ts +136 -11
  190. package/dist/runtime/dom/listenerSummary.js +361 -22
  191. package/dist/runtime/dom/pageActivity.d.ts +41 -0
  192. package/dist/runtime/dom/pageActivity.js +123 -0
  193. package/dist/runtime/dom/reactEventHelpers.d.ts +63 -2
  194. package/dist/runtime/dom/reactEventHelpers.js +220 -41
  195. package/dist/runtime/dom/targetNode.d.ts +80 -27
  196. package/dist/runtime/dom/targetNode.js +249 -33
  197. package/dist/runtime/dom/wait.d.ts +25 -0
  198. package/dist/runtime/dom/wait.js +199 -0
  199. package/dist/runtime/dom/waitCondition.d.ts +71 -0
  200. package/dist/runtime/dom/waitCondition.js +75 -0
  201. package/dist/runtime/page/emulation.d.ts +71 -0
  202. package/dist/runtime/page/emulation.js +117 -0
  203. package/dist/runtime/page/loadingState.d.ts +36 -0
  204. package/dist/runtime/page/loadingState.js +86 -0
  205. package/dist/runtime/page/navigation.d.ts +46 -2
  206. package/dist/runtime/page/navigation.js +69 -33
  207. package/dist/session/QueryCacheManager.d.ts +11 -1
  208. package/dist/session/QueryCacheManager.js +25 -3
  209. package/dist/session/chromeOwners.d.ts +34 -0
  210. package/dist/session/chromeOwners.js +51 -0
  211. package/dist/session/cleanup/staleSession.d.ts +11 -1
  212. package/dist/session/cleanup/staleSession.js +17 -6
  213. package/dist/session/cleanup/userCommands.js +2 -4
  214. package/dist/session/metadata.d.ts +5 -1
  215. package/dist/session/metadata.js +2 -1
  216. package/dist/session/paths.d.ts +77 -3
  217. package/dist/session/paths.js +111 -5
  218. package/dist/session/port.d.ts +31 -7
  219. package/dist/session/port.js +50 -43
  220. package/dist/session/portClaims.d.ts +66 -0
  221. package/dist/session/portClaims.js +284 -0
  222. package/dist/session/sessionList.d.ts +58 -0
  223. package/dist/session/sessionList.js +199 -0
  224. package/dist/session/sessionName.d.ts +46 -0
  225. package/dist/session/sessionName.js +97 -0
  226. package/dist/telemetry/a11y.d.ts +18 -3
  227. package/dist/telemetry/a11y.js +170 -29
  228. package/dist/telemetry/console.d.ts +1 -0
  229. package/dist/telemetry/console.js +100 -5
  230. package/dist/telemetry/network.js +3 -1
  231. package/dist/telemetry/requestKinds.d.ts +32 -0
  232. package/dist/telemetry/requestKinds.js +61 -0
  233. package/dist/telemetry/requestState.d.ts +31 -0
  234. package/dist/telemetry/requestState.js +38 -0
  235. package/dist/types.d.ts +112 -3
  236. package/dist/ui/formatters/a11y.js +3 -0
  237. package/dist/ui/formatters/console/chronological.d.ts +8 -0
  238. package/dist/ui/formatters/console/chronological.js +17 -4
  239. package/dist/ui/formatters/console/json.js +3 -4
  240. package/dist/ui/formatters/console/shared.d.ts +12 -0
  241. package/dist/ui/formatters/console.d.ts +2 -2
  242. package/dist/ui/formatters/console.js +1 -1
  243. package/dist/ui/formatters/details.d.ts +8 -0
  244. package/dist/ui/formatters/details.js +61 -4
  245. package/dist/ui/formatters/dom.d.ts +27 -14
  246. package/dist/ui/formatters/dom.js +88 -59
  247. package/dist/ui/formatters/form.js +29 -18
  248. package/dist/ui/formatters/inspect.d.ts +39 -0
  249. package/dist/ui/formatters/inspect.js +596 -0
  250. package/dist/ui/formatters/keyAttributes.d.ts +19 -0
  251. package/dist/ui/formatters/keyAttributes.js +84 -0
  252. package/dist/ui/formatters/layout.d.ts +31 -0
  253. package/dist/ui/formatters/layout.js +53 -0
  254. package/dist/ui/formatters/listeners.d.ts +3 -2
  255. package/dist/ui/formatters/listeners.js +73 -9
  256. package/dist/ui/formatters/networkHeaders.d.ts +13 -0
  257. package/dist/ui/formatters/networkHeaders.js +36 -3
  258. package/dist/ui/formatters/networkList.d.ts +29 -1
  259. package/dist/ui/formatters/networkList.js +86 -20
  260. package/dist/ui/formatters/preview.js +2 -1
  261. package/dist/ui/formatters/requestStatus.d.ts +1 -17
  262. package/dist/ui/formatters/requestStatus.js +2 -30
  263. package/dist/ui/formatters/sessions.d.ts +12 -0
  264. package/dist/ui/formatters/sessions.js +40 -0
  265. package/dist/ui/formatters/status.d.ts +21 -2
  266. package/dist/ui/formatters/status.js +47 -10
  267. package/dist/ui/formatters/triggeredRequests.d.ts +36 -0
  268. package/dist/ui/formatters/triggeredRequests.js +65 -0
  269. package/dist/ui/formatting.d.ts +19 -0
  270. package/dist/ui/formatting.js +31 -36
  271. package/dist/ui/messages/chrome.d.ts +9 -0
  272. package/dist/ui/messages/chrome.js +17 -5
  273. package/dist/ui/messages/commands.d.ts +504 -14
  274. package/dist/ui/messages/commands.js +835 -21
  275. package/dist/ui/messages/consoleMessages.d.ts +10 -0
  276. package/dist/ui/messages/consoleMessages.js +17 -0
  277. package/dist/ui/messages/hints.js +2 -1
  278. package/dist/ui/messages/networkMessages.d.ts +14 -0
  279. package/dist/ui/messages/networkMessages.js +18 -0
  280. package/dist/ui/messages/preview.js +5 -4
  281. package/dist/ui/messages/session.d.ts +30 -21
  282. package/dist/ui/messages/session.js +48 -26
  283. package/dist/ui/messages/sessionCommand.d.ts +43 -0
  284. package/dist/ui/messages/sessionCommand.js +52 -0
  285. package/dist/utils/async.d.ts +17 -0
  286. package/dist/utils/async.js +36 -0
  287. package/dist/utils/color.d.ts +84 -0
  288. package/dist/utils/color.js +376 -0
  289. package/dist/utils/cssValues.d.ts +109 -0
  290. package/dist/utils/cssValues.js +236 -0
  291. package/dist/utils/http.d.ts +22 -1
  292. package/dist/utils/http.js +28 -9
  293. package/dist/utils/selectorFilters.d.ts +48 -8
  294. package/dist/utils/selectorFilters.js +296 -53
  295. package/dist/utils/shellDetection.d.ts +8 -2
  296. package/dist/utils/shellDetection.js +120 -33
  297. package/dist/utils/suggestions.d.ts +26 -0
  298. package/dist/utils/suggestions.js +73 -0
  299. package/dist/utils/taskMappings.js +10 -0
  300. package/dist/utils/url.d.ts +12 -2
  301. package/dist/utils/url.js +69 -7
  302. package/package.json +1 -1
  303. package/dist/ui/formatters/sessionFormatters.d.ts +0 -58
  304. package/dist/ui/formatters/sessionFormatters.js +0 -121
@@ -0,0 +1,365 @@
1
+ /**
2
+ * Page-side functions of `bdg dom listeners`: what only the page can tell
3
+ * about an element's listeners (handler names and identities, React root
4
+ * containers, the handlers behind jQuery's dispatcher and Preact's event
5
+ * proxy, React's `on…` props of the element and its ancestors, the
6
+ * element's iframe).
7
+ *
8
+ * Each piece is a function expression in a string, combined into
9
+ * {@link ELEMENT_INFO_JS}; every lookup of page globals is guarded, so a
10
+ * page with odd globals (a throwing `jQuery` getter) only loses that detail.
11
+ */
12
+ /** Most jQuery handlers resolved per call; the rest keep jQuery's dispatcher */
13
+ export const MAX_JQUERY_HANDLERS = 50;
14
+ /** Most React prop handlers resolved per call; the rest are counted */
15
+ export const MAX_REACT_HANDLERS = 50;
16
+ /** `(element, view) => string | null`: the iframe element holding the element's document */
17
+ const FRAME_OF_JS = `(element, view) => {
18
+ try {
19
+ const owner = view && view.frameElement;
20
+ return owner ? owner.tagName.toLowerCase() + (owner.id ? '#' + owner.id : '') : null;
21
+ } catch (e) { return null; }
22
+ }`;
23
+ /** `(node) => boolean`: whether the node is a React root container */
24
+ const REACT_ROOT_JS = `(node) => {
25
+ try {
26
+ return !!node && node.nodeType === 1 &&
27
+ ('_reactRootContainer' in node || Object.keys(node).some((key) => key.startsWith('__reactContainer$')));
28
+ } catch (e) { return false; }
29
+ }`;
30
+ /** `(view) => jQuery | undefined`: the page's jQuery, when it has one */
31
+ const JQUERY_OF_JS = `(view) => {
32
+ try {
33
+ if (!view) return undefined;
34
+ return [view.jQuery, view.$].find((c) => c && typeof c._data === 'function');
35
+ } catch (e) { return undefined; }
36
+ }`;
37
+ /**
38
+ * `(jq, element, node, type, handler) => handleObj[] | null`: the jQuery
39
+ * handlers that run for `element` when `handler` is jQuery's dispatcher on
40
+ * `node` (delegates only when the element, or an element between it and
41
+ * `node`, matches their selector); null when it is not the dispatcher.
42
+ */
43
+ const JQUERY_HANDLERS_JS = `(jq, element, node, type, handler) => {
44
+ try {
45
+ if (typeof handler !== 'function') return null;
46
+ const data = jq._data(node);
47
+ if (!data || data.handle !== handler || !data.events) return null;
48
+ const find = jq.find;
49
+ const matches = (el, selector) => {
50
+ try {
51
+ return find && typeof find.matchesSelector === 'function' ? find.matchesSelector(el, selector) : el.matches(selector);
52
+ } catch (e) { return false; }
53
+ };
54
+ const delegatedTo = (selector) => {
55
+ for (let el = element; el && el !== node; el = el.parentNode) {
56
+ if (el.nodeType === 1 && matches(el, selector)) return true;
57
+ }
58
+ return false;
59
+ };
60
+ return Array.from(data.events[type] || []).filter((h) => !h.selector || delegatedTo(h.selector));
61
+ } catch (e) { return null; }
62
+ }`;
63
+ /**
64
+ * `(object, key) => value`: an own data property, read without running a
65
+ * getter the page may have defined (undefined for accessors and on errors).
66
+ */
67
+ const OWN_VALUE_JS = `(object, key) => {
68
+ try {
69
+ const descriptor = object ? Object.getOwnPropertyDescriptor(object, key) : undefined;
70
+ return descriptor ? descriptor.value : undefined;
71
+ } catch (e) { return undefined; }
72
+ }`;
73
+ /**
74
+ * `(node, prefixes) => value`: the value of the node's own key starting with
75
+ * one of `prefixes` (React's keys end in a random suffix).
76
+ */
77
+ const REACT_KEY_JS = `(node, prefixes) => {
78
+ try {
79
+ const key = Object.keys(node).find((k) => prefixes.some((prefix) => k.startsWith(prefix)));
80
+ return key === undefined ? undefined : (${OWN_VALUE_JS})(node, key);
81
+ } catch (e) { return undefined; }
82
+ }`;
83
+ /** `(node) => fiber | undefined`: React's fiber of a DOM element */
84
+ const REACT_FIBER_JS = `(node) => (${REACT_KEY_JS})(node, ['__reactFiber$', '__reactInternalInstance$'])`;
85
+ /**
86
+ * `(node) => object | null`: the props React rendered on a DOM element:
87
+ * `__reactProps$…` (React 17-19), `__reactEventHandlers$…` (React 16), else
88
+ * the `memoizedProps` of its fiber.
89
+ */
90
+ const REACT_PROPS_JS = `(node) => {
91
+ if (!node || node.nodeType !== 1) return null;
92
+ const props = (${REACT_KEY_JS})(node, ['__reactProps$', '__reactEventHandlers$']);
93
+ if (props && typeof props === 'object') return props;
94
+ const memoized = (${OWN_VALUE_JS})((${REACT_FIBER_JS})(node), 'memoizedProps');
95
+ return memoized && typeof memoized === 'object' ? memoized : null;
96
+ }`;
97
+ /** Most fibers walked up from the element (guards against cycles) */
98
+ const MAX_FIBER_STEPS = 1000;
99
+ /**
100
+ * `(fiber) => fiber | null`: for a React root's fiber, the fiber of the
101
+ * nearest React-rendered DOM element at or above its container (where
102
+ * React continues for nested roots: an outer root's handlers run for
103
+ * events in an inner one); null for other fibers and for top-level roots.
104
+ */
105
+ const OUTER_ROOT_FIBER_JS = `(fiber) => {
106
+ const own = ${OWN_VALUE_JS};
107
+ const container = own(own(fiber, 'stateNode'), 'containerInfo');
108
+ try {
109
+ for (let node = container; node && typeof node === 'object'; node = node.parentNode) {
110
+ const outer = (${REACT_FIBER_JS})(node);
111
+ if (outer) return outer;
112
+ }
113
+ } catch (e) { return null; }
114
+ return null;
115
+ }`;
116
+ /**
117
+ * `(element, nodes) => Array<{ node, position }>`: the DOM elements whose
118
+ * React props run for events on the element, nearest first. With a fiber,
119
+ * the host components on its `.return` path (so a portal's React parents
120
+ * count and DOM parents outside the React path don't), continued from a
121
+ * nested root's container into the outer root; `position` is the node's
122
+ * place in the chain, null outside it. Without one, the chain's elements.
123
+ */
124
+ const REACT_HOSTS_JS = `(element, nodes) => {
125
+ const own = ${OWN_VALUE_JS};
126
+ let fiber = (${REACT_FIBER_JS})(element);
127
+ if (!fiber) return nodes.flatMap((node, position) => (node && node.nodeType === 1 ? [{ node, position }] : []));
128
+ const hosts = [];
129
+ const seen = new Set();
130
+ for (let step = 0; fiber && typeof fiber === 'object' && !seen.has(fiber) && step < ${MAX_FIBER_STEPS}; step++) {
131
+ seen.add(fiber);
132
+ const node = own(fiber, 'stateNode');
133
+ if (typeof own(fiber, 'type') === 'string' && node && node.nodeType === 1) {
134
+ const position = nodes.indexOf(node);
135
+ hosts.push({ node, position: position === -1 ? null : position });
136
+ }
137
+ fiber = own(fiber, 'return') || (${OUTER_ROOT_FIBER_JS})(fiber);
138
+ }
139
+ return hosts;
140
+ }`;
141
+ /** Longest source of a minified Preact event proxy (Preact 10 and 11: about 120 characters) */
142
+ const MAX_PREACT_PROXY_LENGTH = 200;
143
+ /**
144
+ * `(source, read) => boolean`: whether a proxy source calls the handler it
145
+ * reads (`read`: the match of `this.<key>[<event>.type + …]`) with the
146
+ * event, directly (`this.l[e.type + false](e)`) or through a variable
147
+ * (`var t = this.l[u.type + n]; … return t(l.event ? l.event(u) : u)`).
148
+ */
149
+ const CALLS_READ_HANDLER_JS = `(source, read) => {
150
+ const event = read[2];
151
+ const passesEvent = (from) => {
152
+ const open = source.indexOf('(', from);
153
+ const close = source.indexOf(')', open);
154
+ if (open === -1 || close === -1 || source.slice(from, open).trim() !== '') return false;
155
+ return source.slice(open + 1, close).split(/[^\\w$]+/).includes(event);
156
+ };
157
+ const end = read.index + read[0].length;
158
+ if (passesEvent(end)) return true;
159
+ const assigned = /([\\w$]+)\\s*=\\s*$/.exec(source.slice(0, read.index));
160
+ if (!assigned) return false;
161
+ const variable = assigned[1];
162
+ for (let at = source.indexOf(variable, end); at !== -1; at = source.indexOf(variable, at + 1)) {
163
+ const before = source[at - 1] || '';
164
+ if (/[\\w$.]/.test(before)) continue;
165
+ if (passesEvent(at + variable.length)) return true;
166
+ }
167
+ return false;
168
+ }`;
169
+ /**
170
+ * `(node, type, capture, handler) => function | null`: the handler Preact
171
+ * runs from `handler` when it is Preact's event proxy on `node`. Preact
172
+ * keeps an element's handlers in an object on the element under a mangled
173
+ * key (`l` in Preact 10, `__e` in 11, `_listeners` unmangled), keyed by
174
+ * event type plus the capture flag (`clickfalse`); the key is read from the
175
+ * proxy's own source (`this.l[e.type + useCapture]`), so it follows
176
+ * Preact's renames. A proxy named `eventProxy`/`eventProxyCapture`
177
+ * (unminified builds; Preact 8 keys by type alone) is accepted as such;
178
+ * any other must look like Preact's minified one: a short function whose
179
+ * key holds a function for exactly the type plus capture flag, which it
180
+ * calls with the event. A generic dispatcher (`this.handlers[e.type](e)`)
181
+ * is left alone.
182
+ */
183
+ const PREACT_HANDLER_JS = `(node, type, capture, handler) => {
184
+ const own = ${OWN_VALUE_JS};
185
+ try {
186
+ if (typeof handler !== 'function' || !node || typeof node !== 'object') return null;
187
+ const source = Function.prototype.toString.call(handler);
188
+ const read = /this\\.([\\w$]+)\\[([\\w$]+)\\.type(?:\\s*\\+\\s*(![01]|true|false|[\\w$]+))?\\s*\\]/.exec(source);
189
+ const store = read ? own(node, read[1]) : undefined;
190
+ if (!store || typeof store !== 'object') return null;
191
+ const flag = { true: true, '!0': true, false: false, '!1': false }[read[3]];
192
+ if (flag !== undefined && flag !== capture) return null;
193
+ const fn = own(store, read[3] ? type + capture : type);
194
+ if (typeof fn !== 'function') return null;
195
+ const name = own(handler, 'name');
196
+ if (name === 'eventProxy' || name === 'eventProxyCapture') return fn;
197
+ const minified = read[3] && source.length < ${MAX_PREACT_PROXY_LENGTH};
198
+ return minified && (${CALLS_READ_HANDLER_JS})(source, read) ? fn : null;
199
+ } catch (e) { return null; }
200
+ }`;
201
+ /** `(node) => string`: CDP-like description of an element, e.g. `div#app.card` */
202
+ const DESCRIBE_NODE_JS = `(node) => {
203
+ try {
204
+ const classes = Array.from(node.classList || []).map((c) => '.' + c).join('');
205
+ return String(node.localName || 'element') + (node.id ? '#' + node.id : '') + classes;
206
+ } catch (e) { return 'element'; }
207
+ }`;
208
+ /**
209
+ * `(props) => Array<{ prop, handler, name }>`: the event handler props
210
+ * (`onClick`, `onKeyDownCapture`) among React props, read without
211
+ * running getters.
212
+ */
213
+ const REACT_HANDLER_PROPS_JS = `(props) => {
214
+ const own = ${OWN_VALUE_JS};
215
+ try {
216
+ return Object.keys(props).filter((prop) => /^on[A-Z]/.test(prop)).flatMap((prop) => {
217
+ const handler = own(props, prop);
218
+ if (typeof handler !== 'function') return [];
219
+ const name = own(handler, 'name');
220
+ return [{ prop, handler, name: typeof name === 'string' ? name : '' }];
221
+ });
222
+ } catch (e) { return []; }
223
+ }`;
224
+ /**
225
+ * `(prop) => { type, capture }`: the DOM event type and phase of a React
226
+ * handler prop: `onClick` → click, `onClickCapture` → click in the capture
227
+ * phase, `onDoubleClick` → dblclick, `onFocus`/`onBlur` → focusin/focusout
228
+ * (the events React listens for), `onGotPointerCapture` → gotpointercapture
229
+ * (and `onGotPointerCaptureCapture` its capture phase).
230
+ */
231
+ const REACT_EVENT_TYPE_JS = `(prop) => {
232
+ const base = prop.slice(2);
233
+ const capture = base.endsWith('Capture') && !/^(?:Got|Lost)PointerCapture$/.test(base);
234
+ const name = (capture ? base.slice(0, -7) : base).toLowerCase();
235
+ const types = { doubleclick: 'dblclick', focus: 'focusin', blur: 'focusout' };
236
+ return { type: types[name] || name, capture };
237
+ }`;
238
+ /**
239
+ * Event types React does not bubble to parents (their bubble-phase props on
240
+ * ancestors never run for the element): enter/leave, scroll (React 17+),
241
+ * and the events React listens for on the element itself (media, load, …).
242
+ */
243
+ const REACT_NON_BUBBLING_TYPES = [
244
+ 'mouseenter',
245
+ 'mouseleave',
246
+ 'pointerenter',
247
+ 'pointerleave',
248
+ 'scroll',
249
+ 'scrollend',
250
+ 'load',
251
+ 'error',
252
+ 'abort',
253
+ 'cancel',
254
+ 'close',
255
+ 'invalid',
256
+ 'toggle',
257
+ 'canplay',
258
+ 'canplaythrough',
259
+ 'durationchange',
260
+ 'emptied',
261
+ 'encrypted',
262
+ 'ended',
263
+ 'loadeddata',
264
+ 'loadedmetadata',
265
+ 'loadstart',
266
+ 'pause',
267
+ 'play',
268
+ 'playing',
269
+ 'progress',
270
+ 'ratechange',
271
+ 'seeked',
272
+ 'seeking',
273
+ 'stalled',
274
+ 'suspend',
275
+ 'timeupdate',
276
+ 'volumechange',
277
+ 'waiting',
278
+ ];
279
+ /**
280
+ * `(element, nodes, wanted, fns) => { react, reactSkipped }`: the React
281
+ * `on…` props that run for events on the element (its own, and bubbling or
282
+ * capture ones of its React parents), limited to the `wanted` types (all
283
+ * when null); their functions are pushed to `fns`.
284
+ */
285
+ const REACT_HANDLERS_JS = `(element, nodes, wanted, fns) => {
286
+ const nonBubbling = new Set(${JSON.stringify(REACT_NON_BUBBLING_TYPES)});
287
+ const react = [];
288
+ let reactSkipped = 0;
289
+ (${REACT_HOSTS_JS})(element, nodes).forEach(({ node, position }, depth) => {
290
+ const props = (${REACT_PROPS_JS})(node);
291
+ if (!props) return;
292
+ for (const { prop, handler, name } of (${REACT_HANDLER_PROPS_JS})(props)) {
293
+ const { type, capture } = (${REACT_EVENT_TYPE_JS})(prop);
294
+ if ((wanted && !wanted.has(type)) || (depth > 0 && !capture && nonBubbling.has(type))) continue;
295
+ if (react.length >= ${MAX_REACT_HANDLERS}) { reactSkipped++; continue; }
296
+ fns.push(handler);
297
+ react.push({ position, ...(position === null && { node: (${DESCRIBE_NODE_JS})(node) }), prop, type, capture, name });
298
+ }
299
+ });
300
+ return { react, reactSkipped };
301
+ }`;
302
+ /**
303
+ * Page function, called on the element with the listeners (position in the
304
+ * chain, event type and capture flag of each), the requested event types (null for all;
305
+ * React props are filtered before the limit), then the chain's objects, then each
306
+ * listener's handler, then the function each handler calls (a bound
307
+ * function's target, else null).
308
+ *
309
+ * Returns `[info, ...jQueryAndPreactHandlers, ...reactHandlers]`. `info` has the
310
+ * iframe element holding the element's document (`frame`), a framework
311
+ * label per chain entry (`roots`), per listener the handler's name, the
312
+ * identity and name of the function it calls (equal identities are the same
313
+ * function object) and, for jQuery's dispatcher, the jQuery handlers that
314
+ * run for the element, for Preact's event proxy the handler Preact runs
315
+ * (`preact`); then the React `on…` props that run for the
316
+ * element's events (`react`, see {@link REACT_HANDLERS_JS}). Their functions follow `info` in the same order.
317
+ * After {@link MAX_JQUERY_HANDLERS}, dispatchers stay unresolved and are
318
+ * counted in `jquerySkipped`; after {@link MAX_REACT_HANDLERS}, React props
319
+ * are counted in `reactSkipped`.
320
+ */
321
+ export const ELEMENT_INFO_JS = `function (listeners, types, ...rest) {
322
+ const count = listeners.length;
323
+ const nodes = rest.slice(0, rest.length - 2 * count);
324
+ const handlers = rest.slice(nodes.length, nodes.length + count);
325
+ const targets = rest.slice(nodes.length + count);
326
+ const view = this.ownerDocument && this.ownerDocument.defaultView;
327
+ const jq = (${JQUERY_OF_JS})(view);
328
+ const ids = new Map();
329
+ const identity = (fn) => {
330
+ if (typeof fn !== 'function') return null;
331
+ if (!ids.has(fn)) ids.set(fn, ids.size);
332
+ return ids.get(fn);
333
+ };
334
+ const fns = [];
335
+ let jquerySkipped = 0;
336
+ const describeHandler = (h) => {
337
+ fns.push(h.handler);
338
+ return { type: h.origType || h.type, selector: h.selector || null,
339
+ name: typeof h.handler === 'function' ? h.handler.name : '' };
340
+ };
341
+ const info = listeners.map((listener, i) => {
342
+ const handler = handlers[i];
343
+ const target = typeof targets[i] === 'function' ? targets[i] : handler;
344
+ const entry = { name: typeof handler === 'function' ? handler.name : null, identity: identity(target),
345
+ targetName: typeof target === 'function' ? target.name : null };
346
+ const resolved = jq ? (${JQUERY_HANDLERS_JS})(jq, this, nodes[listener.position], listener.type, handler) : null;
347
+ if (!resolved) {
348
+ const preact = (${PREACT_HANDLER_JS})(nodes[listener.position], listener.type, listener.capture, handler);
349
+ if (!preact) return entry;
350
+ fns.push(preact);
351
+ const preactName = (${OWN_VALUE_JS})(preact, 'name');
352
+ return { ...entry, preact: { name: typeof preactName === 'string' ? preactName : '' } };
353
+ }
354
+ if (fns.length + resolved.length > ${MAX_JQUERY_HANDLERS}) {
355
+ jquerySkipped += resolved.length;
356
+ return entry;
357
+ }
358
+ return { ...entry, jquery: resolved.map(describeHandler) };
359
+ });
360
+ const roots = nodes.map((node) => ((${REACT_ROOT_JS})(node) ? 'React root' : null));
361
+ const wanted = types && types.length > 0 ? new Set(types) : null;
362
+ const { react, reactSkipped } = (${REACT_HANDLERS_JS})(this, nodes, wanted, fns);
363
+ return [{ frame: (${FRAME_OF_JS})(this, view), roots, listeners: info, jquerySkipped, react, reactSkipped }, ...fns];
364
+ }`;
365
+ //# sourceMappingURL=listenerPageScripts.js.map
@@ -6,13 +6,15 @@
6
6
  * these name, place, filter and order them.
7
7
  */
8
8
  import type { Protocol } from '../../connection/typed-cdp.js';
9
- import type { ElementListener, ListenerPlacement } from '../../ipc/protocol/domTypes.js';
9
+ import type { CollapsedListeners, ElementListener, ListenerPlacement } from '../../ipc/protocol/domTypes.js';
10
10
  /** An event target on the path from the element out to its window. */
11
11
  export interface ChainEntry {
12
12
  /** CDP class name, e.g. `HTMLDivElement`, `HTMLDocument`, `Window` */
13
13
  className?: string | undefined;
14
14
  /** CDP description, e.g. `div#root.app` */
15
15
  description?: string | undefined;
16
+ /** Framework recognised on the node, e.g. `React root` */
17
+ framework?: string | undefined;
16
18
  }
17
19
  /** Listeners found on one entry of the chain. */
18
20
  export interface ChainListeners {
@@ -51,22 +53,145 @@ export declare function handlerPreview(source: string | undefined): string;
51
53
  * @returns Name, or '' for anonymous and arrow functions
52
54
  */
53
55
  export declare function functionNameFromSource(source: string | undefined): string;
56
+ /** What the page reported about one listener's handler */
57
+ export interface HandlerDetails {
58
+ /** `Function.name` of the handler */
59
+ name?: string | undefined;
60
+ /**
61
+ * Identity of the function the handler calls (bound functions unwrapped to
62
+ * their target): equal ids are the same function object
63
+ */
64
+ identity?: number | undefined;
65
+ /** `Function.name` of that function */
66
+ targetName?: string | undefined;
67
+ /** Handlers jQuery runs from this listener (set when it is jQuery's dispatcher) */
68
+ jquery?: ResolvedHandler[] | undefined;
69
+ /** The handler Preact runs from this listener (set when it is Preact's event proxy) */
70
+ preact?: FrameworkHandler | undefined;
71
+ }
72
+ /** A framework's handler found behind its dispatcher, of the dispatcher's event type */
73
+ export type FrameworkHandler = Omit<ResolvedHandler, 'type'>;
74
+ /** A handler registered through a framework, found behind its dispatcher */
75
+ export interface ResolvedHandler {
76
+ /** Event type it was registered for */
77
+ type: string;
78
+ /** Delegate selector, for delegated handlers */
79
+ selector?: string | undefined;
80
+ /** `Function.name` */
81
+ name: string;
82
+ /** Function source */
83
+ source?: string | undefined;
84
+ scriptId: string;
85
+ lineNumber: number;
86
+ columnNumber: number;
87
+ }
88
+ /** A React `on…` prop handler of the element or one of its React parents */
89
+ export interface ReactPropHandler extends ResolvedHandler {
90
+ /**
91
+ * Position in the chain of the element the prop is on (0 = the element);
92
+ * null for a React parent outside the chain (the parent of a portal)
93
+ */
94
+ position: number | null;
95
+ /** Description of that element when it is outside the chain */
96
+ node?: string | undefined;
97
+ /** Prop name, e.g. `onClickCapture` */
98
+ prop: string;
99
+ /** Runs in the capture phase (`on…Capture`) */
100
+ capture: boolean;
101
+ }
102
+ /** What to keep in the report */
103
+ export interface ReportOptions {
104
+ /** Event types to keep (default: all) */
105
+ types?: string[] | undefined;
106
+ /** Keep every framework root listener instead of a summary per node */
107
+ all?: boolean | undefined;
108
+ }
109
+ /** The `bdg dom listeners` report */
110
+ export interface ListenerReport {
111
+ listeners: ElementListener[];
112
+ collapsed: CollapsedListeners[];
113
+ }
114
+ /** A report entry with its position in the chain */
115
+ export interface PlacedListener {
116
+ position: number;
117
+ entry: ChainEntry;
118
+ listener: ElementListener;
119
+ /** Identity of the handler's function (unique when unknown) */
120
+ identity: string;
121
+ /** Name of the handler's function, bound functions unwrapped */
122
+ targetName?: string | undefined;
123
+ }
54
124
  /**
55
- * Build the listener report: filtered to `types` (if given), grouped by
56
- * event type (alphabetically), nearest first within a type.
125
+ * Whether a function source is an empty function (`function u0(){}`,
126
+ * `() => {}`): React sets one as `onclick` on clickable elements.
127
+ *
128
+ * @param source - Function source
129
+ * @returns True for a handler that does nothing
130
+ */
131
+ export declare function isNoopSource(source: string | undefined): boolean;
132
+ /**
133
+ * Collapse framework roots: on a recognised React root container (not the
134
+ * element itself), function objects that each listen for several event
135
+ * types, and together for many, are React's dispatchers. Each root's
136
+ * dispatchers become one summary entry; other multi-type handlers (an
137
+ * analytics listener on `document`) are kept as they are.
138
+ *
139
+ * @param placed - Report entries
140
+ * @returns Entries kept as they are, and one summary per framework root
141
+ */
142
+ export declare function collapseFrameworkRoots(placed: PlacedListener[]): {
143
+ kept: PlacedListener[];
144
+ collapsed: CollapsedListeners[];
145
+ };
146
+ /**
147
+ * Build the listener report: React's `on…` props added, filtered to `types`
148
+ * (if given), framework roots collapsed (unless `all`), grouped by event
149
+ * type with the handlers nearest the element first (see {@link orderListeners}).
57
150
  *
58
151
  * @param found - Listeners per chain entry, in chain order
59
- * @param names - Handler names in the order of the flattened listeners (missing = unknown)
60
- * @param types - Event types to keep (default: all)
61
- * @returns Ordered listeners
152
+ * @param details - Per flattened listener: handler name, jQuery handlers (missing = unknown)
153
+ * @param options - Event types to keep, whether to keep every root listener
154
+ * @param react - React prop handlers of the element and its ancestors
155
+ * @returns Ordered listeners and collapsed framework roots
156
+ */
157
+ export declare function buildListenerReport(found: ChainListeners[], details: HandlerDetails[], options?: ReportOptions, react?: ReactPropHandler[]): ListenerReport;
158
+ /**
159
+ * How an event type without a listener of its own on the element reaches
160
+ * its handlers:
161
+ * - `react`: React runs `on…` props listed in the report (from its root)
162
+ * - `react-root`: a React root listens for it, but no `on…` prop was found
163
+ * - `jquery`: jQuery runs delegated handlers listed in the report
164
+ * - `delegated`: plain listeners on ancestors, document or window
62
165
  */
63
- export declare function buildListenerReport(found: ChainListeners[], names: Array<string | undefined>, types?: string[]): ElementListener[];
166
+ export type DelegationKind = 'react' | 'react-root' | 'jquery' | 'delegated';
167
+ /** Interaction event types handled the same way, for the report's notes */
168
+ export interface DelegationNote {
169
+ kind: DelegationKind;
170
+ /** Event types, in report order */
171
+ types: string[];
172
+ /** Those of `types` whose only listener on the element is a no-op (React's placeholder) */
173
+ placeholderTypes: string[];
174
+ /** The node handling them: the React root container or jQuery's node */
175
+ node?: string | undefined;
176
+ }
64
177
  /**
65
- * Interaction event types that have listeners, but none on the element
66
- * itself: frameworks (React, jQuery) handle these by delegation.
178
+ * Notes for interaction event types the element has no listener of its own
179
+ * for (no-ops aside), grouped by how they reach their handlers: React `on…`
180
+ * props, a React root without props, jQuery delegation, or plain listeners
181
+ * on ancestors, document or window.
67
182
  *
68
183
  * @param listeners - Listener report
69
- * @returns Event types, in report order
184
+ * @param collapsed - Collapsed framework roots
185
+ * @returns Notes, React first; none when every type has a listener on the element
186
+ */
187
+ export declare function delegationNotes(listeners: ElementListener[], collapsed?: CollapsedListeners[]): DelegationNote[];
188
+ /**
189
+ * Event types with listeners that a `--type` value probably meant, for an
190
+ * empty result: `Click` → `click`, `onclick` → `click`.
191
+ *
192
+ * @param requested - Types asked for
193
+ * @param available - Types that have listeners
194
+ * @returns Suggestions (none when nothing is close)
70
195
  */
71
- export declare function delegatedOnlyTypes(listeners: ElementListener[]): string[];
196
+ export declare function suggestEventTypes(requested: string[], available: string[]): string[];
72
197
  //# sourceMappingURL=listenerSummary.d.ts.map