@rezi-ui/core 0.1.0-alpha.60 → 0.1.0-alpha.63

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 (345) hide show
  1. package/dist/app/createApp/breadcrumbs.d.ts +38 -0
  2. package/dist/app/createApp/breadcrumbs.d.ts.map +1 -0
  3. package/dist/app/createApp/breadcrumbs.js +65 -0
  4. package/dist/app/createApp/breadcrumbs.js.map +1 -0
  5. package/dist/app/createApp/config.d.ts +25 -0
  6. package/dist/app/createApp/config.d.ts.map +1 -0
  7. package/dist/app/createApp/config.js +130 -0
  8. package/dist/app/createApp/config.js.map +1 -0
  9. package/dist/app/createApp/eventLoop.d.ts +95 -0
  10. package/dist/app/createApp/eventLoop.d.ts.map +1 -0
  11. package/dist/app/createApp/eventLoop.js +384 -0
  12. package/dist/app/createApp/eventLoop.js.map +1 -0
  13. package/dist/app/createApp/guards.d.ts +21 -0
  14. package/dist/app/createApp/guards.d.ts.map +1 -0
  15. package/dist/app/createApp/guards.js +54 -0
  16. package/dist/app/createApp/guards.js.map +1 -0
  17. package/dist/app/createApp/keybindings.d.ts +28 -0
  18. package/dist/app/createApp/keybindings.d.ts.map +1 -0
  19. package/dist/app/createApp/keybindings.js +113 -0
  20. package/dist/app/createApp/keybindings.js.map +1 -0
  21. package/dist/app/createApp/renderLoop.d.ts +64 -0
  22. package/dist/app/createApp/renderLoop.d.ts.map +1 -0
  23. package/dist/app/createApp/renderLoop.js +305 -0
  24. package/dist/app/createApp/renderLoop.js.map +1 -0
  25. package/dist/app/createApp.d.ts +3 -39
  26. package/dist/app/createApp.d.ts.map +1 -1
  27. package/dist/app/createApp.js +403 -1205
  28. package/dist/app/createApp.js.map +1 -1
  29. package/dist/app/widgetRenderer/constraintState.d.ts +98 -0
  30. package/dist/app/widgetRenderer/constraintState.d.ts.map +1 -0
  31. package/dist/app/widgetRenderer/constraintState.js +563 -0
  32. package/dist/app/widgetRenderer/constraintState.js.map +1 -0
  33. package/dist/app/widgetRenderer/fileNodeCache.d.ts +2 -0
  34. package/dist/app/widgetRenderer/fileNodeCache.d.ts.map +1 -1
  35. package/dist/app/widgetRenderer/fileNodeCache.js +31 -0
  36. package/dist/app/widgetRenderer/fileNodeCache.js.map +1 -1
  37. package/dist/app/widgetRenderer/filePickerRouting.d.ts +12 -1
  38. package/dist/app/widgetRenderer/filePickerRouting.d.ts.map +1 -1
  39. package/dist/app/widgetRenderer/filePickerRouting.js +63 -14
  40. package/dist/app/widgetRenderer/filePickerRouting.js.map +1 -1
  41. package/dist/app/widgetRenderer/focusState.d.ts +46 -0
  42. package/dist/app/widgetRenderer/focusState.d.ts.map +1 -0
  43. package/dist/app/widgetRenderer/focusState.js +122 -0
  44. package/dist/app/widgetRenderer/focusState.js.map +1 -0
  45. package/dist/app/widgetRenderer/keyboardRouting.d.ts.map +1 -1
  46. package/dist/app/widgetRenderer/keyboardRouting.js.map +1 -1
  47. package/dist/app/widgetRenderer/mouseRouting.d.ts +5 -0
  48. package/dist/app/widgetRenderer/mouseRouting.d.ts.map +1 -1
  49. package/dist/app/widgetRenderer/mouseRouting.js +78 -8
  50. package/dist/app/widgetRenderer/mouseRouting.js.map +1 -1
  51. package/dist/app/widgetRenderer/overlayShortcuts.d.ts.map +1 -1
  52. package/dist/app/widgetRenderer/overlayShortcuts.js +14 -4
  53. package/dist/app/widgetRenderer/overlayShortcuts.js.map +1 -1
  54. package/dist/app/widgetRenderer/overlayState.d.ts +198 -0
  55. package/dist/app/widgetRenderer/overlayState.d.ts.map +1 -0
  56. package/dist/app/widgetRenderer/overlayState.js +590 -0
  57. package/dist/app/widgetRenderer/overlayState.js.map +1 -0
  58. package/dist/app/widgetRenderer/routeEngineEvent.d.ts +189 -0
  59. package/dist/app/widgetRenderer/routeEngineEvent.d.ts.map +1 -0
  60. package/dist/app/widgetRenderer/routeEngineEvent.js +527 -0
  61. package/dist/app/widgetRenderer/routeEngineEvent.js.map +1 -0
  62. package/dist/app/widgetRenderer.d.ts +2 -1
  63. package/dist/app/widgetRenderer.d.ts.map +1 -1
  64. package/dist/app/widgetRenderer.js +334 -1707
  65. package/dist/app/widgetRenderer.js.map +1 -1
  66. package/dist/forms/internal/arrayState.d.ts +35 -0
  67. package/dist/forms/internal/arrayState.d.ts.map +1 -0
  68. package/dist/forms/internal/arrayState.js +238 -0
  69. package/dist/forms/internal/arrayState.js.map +1 -0
  70. package/dist/forms/internal/bindings.d.ts +46 -0
  71. package/dist/forms/internal/bindings.d.ts.map +1 -0
  72. package/dist/forms/internal/bindings.js +161 -0
  73. package/dist/forms/internal/bindings.js.map +1 -0
  74. package/dist/forms/internal/dev.d.ts +4 -0
  75. package/dist/forms/internal/dev.d.ts.map +1 -0
  76. package/dist/forms/internal/dev.js +21 -0
  77. package/dist/forms/internal/dev.js.map +1 -0
  78. package/dist/forms/internal/state.d.ts +52 -0
  79. package/dist/forms/internal/state.d.ts.map +1 -0
  80. package/dist/forms/internal/state.js +240 -0
  81. package/dist/forms/internal/state.js.map +1 -0
  82. package/dist/forms/internal/submit.d.ts +43 -0
  83. package/dist/forms/internal/submit.d.ts.map +1 -0
  84. package/dist/forms/internal/submit.js +165 -0
  85. package/dist/forms/internal/submit.js.map +1 -0
  86. package/dist/forms/internal/wizard.d.ts +53 -0
  87. package/dist/forms/internal/wizard.d.ts.map +1 -0
  88. package/dist/forms/internal/wizard.js +311 -0
  89. package/dist/forms/internal/wizard.js.map +1 -0
  90. package/dist/forms/useForm.d.ts.map +1 -1
  91. package/dist/forms/useForm.js +90 -1117
  92. package/dist/forms/useForm.js.map +1 -1
  93. package/dist/index.d.ts +1 -1
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/index.js +1 -1
  96. package/dist/index.js.map +1 -1
  97. package/dist/keybindings/manager.d.ts.map +1 -1
  98. package/dist/keybindings/manager.js.map +1 -1
  99. package/dist/keybindings/parser.d.ts.map +1 -1
  100. package/dist/keybindings/parser.js +10 -5
  101. package/dist/keybindings/parser.js.map +1 -1
  102. package/dist/layout/dropdownGeometry.d.ts +8 -0
  103. package/dist/layout/dropdownGeometry.d.ts.map +1 -1
  104. package/dist/layout/dropdownGeometry.js +40 -0
  105. package/dist/layout/dropdownGeometry.js.map +1 -1
  106. package/dist/layout/engine/layoutEngine.js +1 -1
  107. package/dist/layout/engine/layoutEngine.js.map +1 -1
  108. package/dist/layout/kinds/overlays.d.ts.map +1 -1
  109. package/dist/layout/kinds/stack.d.ts +1 -3
  110. package/dist/layout/kinds/stack.d.ts.map +1 -1
  111. package/dist/layout/kinds/stack.js +11 -1523
  112. package/dist/layout/kinds/stack.js.map +1 -1
  113. package/dist/layout/kinds/stackParts/axis.d.ts +32 -0
  114. package/dist/layout/kinds/stackParts/axis.d.ts.map +1 -0
  115. package/dist/layout/kinds/stackParts/axis.js +61 -0
  116. package/dist/layout/kinds/stackParts/axis.js.map +1 -0
  117. package/dist/layout/kinds/stackParts/constraintPlan.d.ts +18 -0
  118. package/dist/layout/kinds/stackParts/constraintPlan.d.ts.map +1 -0
  119. package/dist/layout/kinds/stackParts/constraintPlan.js +434 -0
  120. package/dist/layout/kinds/stackParts/constraintPlan.js.map +1 -0
  121. package/dist/layout/kinds/stackParts/layout.d.ts +6 -0
  122. package/dist/layout/kinds/stackParts/layout.d.ts.map +1 -0
  123. package/dist/layout/kinds/stackParts/layout.js +376 -0
  124. package/dist/layout/kinds/stackParts/layout.js.map +1 -0
  125. package/dist/layout/kinds/stackParts/measure.d.ts +6 -0
  126. package/dist/layout/kinds/stackParts/measure.d.ts.map +1 -0
  127. package/dist/layout/kinds/stackParts/measure.js +212 -0
  128. package/dist/layout/kinds/stackParts/measure.js.map +1 -0
  129. package/dist/layout/kinds/stackParts/shared.d.ts +31 -0
  130. package/dist/layout/kinds/stackParts/shared.d.ts.map +1 -0
  131. package/dist/layout/kinds/stackParts/shared.js +94 -0
  132. package/dist/layout/kinds/stackParts/shared.js.map +1 -0
  133. package/dist/layout/kinds/stackParts/wrap.d.ts +26 -0
  134. package/dist/layout/kinds/stackParts/wrap.d.ts.map +1 -0
  135. package/dist/layout/kinds/stackParts/wrap.js +374 -0
  136. package/dist/layout/kinds/stackParts/wrap.js.map +1 -0
  137. package/dist/layout/validate/interactive.d.ts +106 -0
  138. package/dist/layout/validate/interactive.d.ts.map +1 -0
  139. package/dist/layout/validate/interactive.js +430 -0
  140. package/dist/layout/validate/interactive.js.map +1 -0
  141. package/dist/layout/validate/layoutConstraints.d.ts +51 -0
  142. package/dist/layout/validate/layoutConstraints.d.ts.map +1 -0
  143. package/dist/layout/validate/layoutConstraints.js +100 -0
  144. package/dist/layout/validate/layoutConstraints.js.map +1 -0
  145. package/dist/layout/validate/primitives.d.ts +31 -0
  146. package/dist/layout/validate/primitives.d.ts.map +1 -0
  147. package/dist/layout/validate/primitives.js +299 -0
  148. package/dist/layout/validate/primitives.js.map +1 -0
  149. package/dist/layout/validate/shared.d.ts +23 -0
  150. package/dist/layout/validate/shared.d.ts.map +1 -0
  151. package/dist/layout/validate/shared.js +32 -0
  152. package/dist/layout/validate/shared.js.map +1 -0
  153. package/dist/layout/validate/spacing.d.ts +21 -0
  154. package/dist/layout/validate/spacing.d.ts.map +1 -0
  155. package/dist/layout/validate/spacing.js +33 -0
  156. package/dist/layout/validate/spacing.js.map +1 -0
  157. package/dist/layout/validateProps.d.ts +5 -159
  158. package/dist/layout/validateProps.d.ts.map +1 -1
  159. package/dist/layout/validateProps.js +1 -832
  160. package/dist/layout/validateProps.js.map +1 -1
  161. package/dist/pipeline.js +1 -1
  162. package/dist/pipeline.js.map +1 -1
  163. package/dist/renderer/renderToDrawlist/renderTree.d.ts +1 -1
  164. package/dist/renderer/renderToDrawlist/renderTree.d.ts.map +1 -1
  165. package/dist/renderer/renderToDrawlist/renderTree.js +3 -3
  166. package/dist/renderer/renderToDrawlist/renderTree.js.map +1 -1
  167. package/dist/renderer/renderToDrawlist/types.d.ts +2 -0
  168. package/dist/renderer/renderToDrawlist/types.d.ts.map +1 -1
  169. package/dist/renderer/renderToDrawlist/widgets/containers.d.ts.map +1 -1
  170. package/dist/renderer/renderToDrawlist/widgets/containers.js +1 -1
  171. package/dist/renderer/renderToDrawlist/widgets/containers.js.map +1 -1
  172. package/dist/renderer/renderToDrawlist/widgets/files.d.ts +2 -1
  173. package/dist/renderer/renderToDrawlist/widgets/files.d.ts.map +1 -1
  174. package/dist/renderer/renderToDrawlist/widgets/files.js +30 -3
  175. package/dist/renderer/renderToDrawlist/widgets/files.js.map +1 -1
  176. package/dist/renderer/renderToDrawlist/widgets/overlays.d.ts +1 -1
  177. package/dist/renderer/renderToDrawlist/widgets/overlays.d.ts.map +1 -1
  178. package/dist/renderer/renderToDrawlist/widgets/overlays.js +26 -6
  179. package/dist/renderer/renderToDrawlist/widgets/overlays.js.map +1 -1
  180. package/dist/renderer/renderToDrawlist/widgets/renderFormWidgets.d.ts.map +1 -1
  181. package/dist/renderer/renderToDrawlist/widgets/renderFormWidgets.js +52 -18
  182. package/dist/renderer/renderToDrawlist/widgets/renderFormWidgets.js.map +1 -1
  183. package/dist/renderer/renderToDrawlist.d.ts +0 -8
  184. package/dist/renderer/renderToDrawlist.d.ts.map +1 -1
  185. package/dist/renderer/renderToDrawlist.js +1 -9
  186. package/dist/renderer/renderToDrawlist.js.map +1 -1
  187. package/dist/runtime/commit/composite.d.ts +11 -0
  188. package/dist/runtime/commit/composite.d.ts.map +1 -0
  189. package/dist/runtime/commit/composite.js +238 -0
  190. package/dist/runtime/commit/composite.js.map +1 -0
  191. package/dist/runtime/commit/container.d.ts +7 -0
  192. package/dist/runtime/commit/container.d.ts.map +1 -0
  193. package/dist/runtime/commit/container.js +350 -0
  194. package/dist/runtime/commit/container.js.map +1 -0
  195. package/dist/runtime/commit/equality.d.ts +20 -0
  196. package/dist/runtime/commit/equality.d.ts.map +1 -0
  197. package/dist/runtime/commit/equality.js +436 -0
  198. package/dist/runtime/commit/equality.js.map +1 -0
  199. package/dist/runtime/commit/errorBoundary.d.ts +7 -0
  200. package/dist/runtime/commit/errorBoundary.d.ts.map +1 -0
  201. package/dist/runtime/commit/errorBoundary.js +53 -0
  202. package/dist/runtime/commit/errorBoundary.js.map +1 -0
  203. package/dist/runtime/commit/shared.d.ts +138 -0
  204. package/dist/runtime/commit/shared.d.ts.map +1 -0
  205. package/dist/runtime/commit/shared.js +11 -0
  206. package/dist/runtime/commit/shared.js.map +1 -0
  207. package/dist/runtime/commit/transitions.d.ts +9 -0
  208. package/dist/runtime/commit/transitions.d.ts.map +1 -0
  209. package/dist/runtime/commit/transitions.js +93 -0
  210. package/dist/runtime/commit/transitions.js.map +1 -0
  211. package/dist/runtime/commit/validation.d.ts +16 -0
  212. package/dist/runtime/commit/validation.d.ts.map +1 -0
  213. package/dist/runtime/commit/validation.js +157 -0
  214. package/dist/runtime/commit/validation.js.map +1 -0
  215. package/dist/runtime/commit.d.ts +7 -117
  216. package/dist/runtime/commit.d.ts.map +1 -1
  217. package/dist/runtime/commit.js +13 -1394
  218. package/dist/runtime/commit.js.map +1 -1
  219. package/dist/runtime/localState.d.ts +4 -0
  220. package/dist/runtime/localState.d.ts.map +1 -1
  221. package/dist/runtime/localState.js.map +1 -1
  222. package/dist/runtime/widgetMeta/collector.d.ts +77 -0
  223. package/dist/runtime/widgetMeta/collector.d.ts.map +1 -0
  224. package/dist/runtime/widgetMeta/collector.js +293 -0
  225. package/dist/runtime/widgetMeta/collector.js.map +1 -0
  226. package/dist/runtime/widgetMeta/focusContainers.d.ts +44 -0
  227. package/dist/runtime/widgetMeta/focusContainers.d.ts.map +1 -0
  228. package/dist/runtime/widgetMeta/focusContainers.js +190 -0
  229. package/dist/runtime/widgetMeta/focusContainers.js.map +1 -0
  230. package/dist/runtime/widgetMeta/focusInfo.d.ts +19 -0
  231. package/dist/runtime/widgetMeta/focusInfo.d.ts.map +1 -0
  232. package/dist/runtime/widgetMeta/focusInfo.js +172 -0
  233. package/dist/runtime/widgetMeta/focusInfo.js.map +1 -0
  234. package/dist/runtime/widgetMeta/helpers.d.ts +47 -0
  235. package/dist/runtime/widgetMeta/helpers.d.ts.map +1 -0
  236. package/dist/runtime/widgetMeta/helpers.js +182 -0
  237. package/dist/runtime/widgetMeta/helpers.js.map +1 -0
  238. package/dist/runtime/widgetMeta.d.ts +12 -175
  239. package/dist/runtime/widgetMeta.d.ts.map +1 -1
  240. package/dist/runtime/widgetMeta.js +6 -847
  241. package/dist/runtime/widgetMeta.js.map +1 -1
  242. package/dist/ui/capabilities.d.ts.map +1 -1
  243. package/dist/ui/designTokens.d.ts.map +1 -1
  244. package/dist/widgets/accordion.d.ts.map +1 -1
  245. package/dist/widgets/accordion.js +8 -13
  246. package/dist/widgets/accordion.js.map +1 -1
  247. package/dist/widgets/factories/advanced.d.ts +20 -0
  248. package/dist/widgets/factories/advanced.d.ts.map +1 -0
  249. package/dist/widgets/factories/advanced.js +75 -0
  250. package/dist/widgets/factories/advanced.js.map +1 -0
  251. package/dist/widgets/factories/basic.d.ts +14 -0
  252. package/dist/widgets/factories/basic.d.ts.map +1 -0
  253. package/dist/widgets/factories/basic.js +44 -0
  254. package/dist/widgets/factories/basic.js.map +1 -0
  255. package/dist/widgets/factories/feedback.d.ts +20 -0
  256. package/dist/widgets/factories/feedback.d.ts.map +1 -0
  257. package/dist/widgets/factories/feedback.js +102 -0
  258. package/dist/widgets/factories/feedback.js.map +1 -0
  259. package/dist/widgets/factories/helpers.d.ts +41 -0
  260. package/dist/widgets/factories/helpers.d.ts.map +1 -0
  261. package/dist/widgets/factories/helpers.js +72 -0
  262. package/dist/widgets/factories/helpers.js.map +1 -0
  263. package/dist/widgets/factories/interactive.d.ts +15 -0
  264. package/dist/widgets/factories/interactive.d.ts.map +1 -0
  265. package/dist/widgets/factories/interactive.js +46 -0
  266. package/dist/widgets/factories/interactive.js.map +1 -0
  267. package/dist/widgets/factories/layoutShell.d.ts +22 -0
  268. package/dist/widgets/factories/layoutShell.d.ts.map +1 -0
  269. package/dist/widgets/factories/layoutShell.js +190 -0
  270. package/dist/widgets/factories/layoutShell.js.map +1 -0
  271. package/dist/widgets/factories/media.d.ts +14 -0
  272. package/dist/widgets/factories/media.d.ts.map +1 -0
  273. package/dist/widgets/factories/media.js +25 -0
  274. package/dist/widgets/factories/media.js.map +1 -0
  275. package/dist/widgets/factories/navigation.d.ts +10 -0
  276. package/dist/widgets/factories/navigation.d.ts.map +1 -0
  277. package/dist/widgets/factories/navigation.js +24 -0
  278. package/dist/widgets/factories/navigation.js.map +1 -0
  279. package/dist/widgets/field.d.ts +6 -1
  280. package/dist/widgets/field.d.ts.map +1 -1
  281. package/dist/widgets/field.js +8 -2
  282. package/dist/widgets/field.js.map +1 -1
  283. package/dist/widgets/filePicker.d.ts +5 -0
  284. package/dist/widgets/filePicker.d.ts.map +1 -0
  285. package/dist/widgets/filePicker.js +136 -0
  286. package/dist/widgets/filePicker.js.map +1 -0
  287. package/dist/widgets/protocol.d.ts +0 -6
  288. package/dist/widgets/protocol.d.ts.map +1 -1
  289. package/dist/widgets/protocol.js +0 -6
  290. package/dist/widgets/protocol.js.map +1 -1
  291. package/dist/widgets/select.js +1 -1
  292. package/dist/widgets/select.js.map +1 -1
  293. package/dist/widgets/splitPane.d.ts.map +1 -1
  294. package/dist/widgets/splitPane.js.map +1 -1
  295. package/dist/widgets/table.d.ts.map +1 -1
  296. package/dist/widgets/table.js +43 -1
  297. package/dist/widgets/table.js.map +1 -1
  298. package/dist/widgets/tree.d.ts.map +1 -1
  299. package/dist/widgets/types/advanced.d.ts +611 -0
  300. package/dist/widgets/types/advanced.d.ts.map +1 -0
  301. package/dist/widgets/types/advanced.js +2 -0
  302. package/dist/widgets/types/advanced.js.map +1 -0
  303. package/dist/widgets/types/base.d.ts +933 -0
  304. package/dist/widgets/types/base.d.ts.map +1 -0
  305. package/dist/widgets/types/base.js +2 -0
  306. package/dist/widgets/types/base.js.map +1 -0
  307. package/dist/widgets/types/forms.d.ts +136 -0
  308. package/dist/widgets/types/forms.d.ts.map +1 -0
  309. package/dist/widgets/types/forms.js +2 -0
  310. package/dist/widgets/types/forms.js.map +1 -0
  311. package/dist/widgets/types/navigation.d.ts +83 -0
  312. package/dist/widgets/types/navigation.d.ts.map +1 -0
  313. package/dist/widgets/types/navigation.js +2 -0
  314. package/dist/widgets/types/navigation.js.map +1 -0
  315. package/dist/widgets/types/overlaysShell.d.ts +223 -0
  316. package/dist/widgets/types/overlaysShell.d.ts.map +1 -0
  317. package/dist/widgets/types/overlaysShell.js +2 -0
  318. package/dist/widgets/types/overlaysShell.js.map +1 -0
  319. package/dist/widgets/types/table.d.ts +104 -0
  320. package/dist/widgets/types/table.d.ts.map +1 -0
  321. package/dist/widgets/types/table.js +2 -0
  322. package/dist/widgets/types/table.js.map +1 -0
  323. package/dist/widgets/types/tree.d.ts +64 -0
  324. package/dist/widgets/types/tree.d.ts.map +1 -0
  325. package/dist/widgets/types/tree.js +2 -0
  326. package/dist/widgets/types/tree.js.map +1 -0
  327. package/dist/widgets/types.d.ts +14 -2123
  328. package/dist/widgets/types.d.ts.map +1 -1
  329. package/dist/widgets/ui.d.ts +37 -843
  330. package/dist/widgets/ui.d.ts.map +1 -1
  331. package/dist/widgets/ui.js +37 -1262
  332. package/dist/widgets/ui.js.map +1 -1
  333. package/package.json +2 -2
  334. package/dist/constraints/aggregation.d.ts +0 -17
  335. package/dist/constraints/aggregation.d.ts.map +0 -1
  336. package/dist/constraints/aggregation.js +0 -59
  337. package/dist/constraints/aggregation.js.map +0 -1
  338. package/dist/renderer/renderToDrawlist/overflowCulling.d.ts +0 -3
  339. package/dist/renderer/renderToDrawlist/overflowCulling.d.ts.map +0 -1
  340. package/dist/renderer/renderToDrawlist/overflowCulling.js +0 -81
  341. package/dist/renderer/renderToDrawlist/overflowCulling.js.map +0 -1
  342. package/dist/widgets/tests/protocol.test.d.ts +0 -2
  343. package/dist/widgets/tests/protocol.test.d.ts.map +0 -1
  344. package/dist/widgets/tests/protocol.test.js +0 -120
  345. package/dist/widgets/tests/protocol.test.js.map +0 -1
@@ -26,10 +26,8 @@ import { buildConstraintGraph, } from "../constraints/graph.js";
26
26
  import { ConstraintResolutionCache, resolveConstraints, } from "../constraints/resolver.js";
27
27
  import { CURSOR_DEFAULTS } from "../cursor/index.js";
28
28
  import { createDrawlistBuilder } from "../drawlist/index.js";
29
- import { buildTrie, resetChordState, } from "../keybindings/index.js";
30
- import { ZR_MOD_CTRL, } from "../keybindings/keyCodes.js";
29
+ import { buildTrie, resetChordState } from "../keybindings/index.js";
31
30
  import { computeDropdownGeometry } from "../layout/dropdownGeometry.js";
32
- import { hitTestAnyId, hitTestFocusable } from "../layout/hitTest.js";
33
31
  import { layout, measure } from "../layout/layout.js";
34
32
  import { getResponsiveViewport, normalizeBreakpointThresholds, setResponsiveViewport, } from "../layout/responsive.js";
35
33
  import { FRAME_AUDIT_ENABLED, drawlistFingerprint, emitFrameAudit } from "../perf/frameAudit.js";
@@ -44,30 +42,23 @@ import { createInstanceIdAllocator } from "../runtime/instance.js";
44
42
  import { createCompositeInstanceRegistry, runPendingCleanups, runPendingEffects, } from "../runtime/instances.js";
45
43
  import { createLayerRegistry } from "../runtime/layers.js";
46
44
  import { createTableStateStore, createTreeStateStore, createVirtualListStateStore, } from "../runtime/localState.js";
47
- import { routeDropdownKey, routeKeyWithZones, routeLayerEscape, routeMouse, } from "../runtime/router.js";
48
45
  import { createWidgetMetadataCollector, } from "../runtime/widgetMeta.js";
49
46
  import { DEFAULT_TERMINAL_PROFILE } from "../terminalProfile.js";
50
47
  import { getColorTokens } from "../theme/extract.js";
51
- import { deleteRange, getSelectedText, insertText } from "../widgets/codeEditor.js";
52
- import { TOAST_HEIGHT, getToastActionFocusId, parseToastActionFocusId } from "../widgets/toast.js";
53
- import { flattenTree } from "../widgets/tree.js";
48
+ import { parseToastActionFocusId } from "../widgets/toast.js";
54
49
  import { EMPTY_WIDGET_RUNTIME_BREADCRUMBS, } from "./runtimeBreadcrumbs.js";
55
50
  import { readContainerOpacity as readContainerOpacityImpl, rebuildAnimatedRectOverrides as rebuildAnimatedRectOverridesImpl, recomputeAnimatedWidgetPresence as recomputeAnimatedWidgetPresenceImpl, refreshPositionTransitionTracks as refreshPositionTransitionTracksImpl, sampleExitAnimations as sampleExitAnimationsImpl, scheduleExitAnimations as scheduleExitAnimationsImpl, } from "./widgetRenderer/animationTracks.js";
56
- import { routeCodeEditorKeyDown } from "./widgetRenderer/codeEditorRouting.js";
57
- import { kickoffCommandPaletteItemFetches, routeCommandPaletteKeyDown, } from "./widgetRenderer/commandPaletteRouting.js";
51
+ import { kickoffCommandPaletteItemFetches } from "./widgetRenderer/commandPaletteRouting.js";
52
+ import { CONSTRAINT_NODE_PROPS, applyConstraintOverridesToVNode as applyConstraintOverridesToVNodeImpl, buildConstraintResolutionInputs as buildConstraintResolutionInputsImpl, computeConstraintBreadcrumbs as computeConstraintBreadcrumbsImpl, computeConstraintInputKey as computeConstraintInputKeyImpl, describeConstraintGraphFatal as describeConstraintGraphFatalImpl, hasConstraintInputSignatureChange as hasConstraintInputSignatureChangeImpl, rebuildConstraintAffectedPathSet as rebuildConstraintAffectedPathSetImpl, rebuildConstraintExprIndex as rebuildConstraintExprIndexImpl, rebuildConstraintHiddenState as rebuildConstraintHiddenStateImpl, shouldRebuildConstraintGraph as shouldRebuildConstraintGraphImpl, } from "./widgetRenderer/constraintState.js";
58
53
  import { emitIncrementalCursor as emitIncrementalCursorImpl, resolveRuntimeCursorSummary as resolveRuntimeCursorSummaryImpl, snapshotRenderedFrameState as snapshotRenderedFrameStateImpl, updateRuntimeBreadcrumbSnapshot as updateRuntimeBreadcrumbSnapshotImpl, } from "./widgetRenderer/cursorBreadcrumbs.js";
59
54
  import { appendDamageRectForId as appendDamageRectForIdImpl, appendDamageRectForInstanceId as appendDamageRectForInstanceIdImpl, appendDamageRectsForFocusAnnouncers as appendDamageRectsForFocusAnnouncersImpl, clearRuntimeDirtyNodes as clearRuntimeDirtyNodesImpl, collectSelfDirtyInstanceIds as collectSelfDirtyInstanceIdsImpl, collectSpinnerDamageRects as collectSpinnerDamageRectsImpl, collectSubtreeDamageAndRouting as collectSubtreeDamageAndRoutingImpl, computeIdentityDiffDamage as computeIdentityDiffDamageImpl, isDamageAreaTooLarge as isDamageAreaTooLargeImpl, markLayoutDirtyNodes as markLayoutDirtyNodesImpl, markTransientDirtyNodes as markTransientDirtyNodesImpl, normalizeDamageRects as normalizeDamageRectsImpl, propagateDirtyFromPredicate as propagateDirtyFromPredicateImpl, refreshDamageRectIndexesForLayoutSkippedCommit as refreshDamageRectIndexesForLayoutSkippedCommitImpl, shouldAttemptIncrementalRender as shouldAttemptIncrementalRenderImpl, } from "./widgetRenderer/damageTracking.js";
60
55
  import { describeLayoutNode as describeLayoutNodeImpl, emitDevLayoutWarnings as emitDevLayoutWarningsImpl, warnLayoutIssue as warnLayoutIssueImpl, warnShortcutIssue as warnShortcutIssueImpl, } from "./widgetRenderer/devWarnings.js";
61
- import { fileNodeGetChildren, fileNodeGetKey, fileNodeHasChildren, makeFileNodeFlatCache, readFileNodeFlatCache, } from "./widgetRenderer/fileNodeCache.js";
62
- import { routeFilePickerKeyDown, routeFileTreeExplorerKeyDown, } from "./widgetRenderer/filePickerRouting.js";
63
- import { applyInputSnapshot as applyInputSnapshotImpl, getInputUndoStack as getInputUndoStackImpl, readInputSnapshot as readInputSnapshotImpl, routeInputEditingEvent, } from "./widgetRenderer/inputEditing.js";
64
- import { routeCheckboxKeyDown, routeDiffViewerKeyDown, routeLogsConsoleKeyDown, routeRadioGroupKeyDown, routeSelectKeyDown, routeSliderKeyDown, routeTableKeyDown, routeToastActionKeyDown, routeTreeKeyDown, routeVirtualListKeyDown, } from "./widgetRenderer/keyboardRouting.js";
65
- import { routeDropdownMouse, routeFilePickerMouseClick, routeFileTreeExplorerContextMenuMouse, routeFileTreeExplorerMouseClick, routeLayerBackdropMouse, routeMouseWheel, routeSplitPaneMouse, routeTableMouseClick, routeToastMouseDown, routeTreeMouseClick, routeVirtualListMouseClick, } from "./widgetRenderer/mouseRouting.js";
56
+ import { buildFallbackFocusInfo as buildFallbackFocusInfoImpl, captureFocusSnapshotState, findScrollableAncestors as findScrollableAncestorsImpl, invokeFocusZoneCallbacks as invokeFocusZoneCallbacksImpl, restoreFocusSnapshotState, } from "./widgetRenderer/focusState.js";
57
+ import { applyInputSnapshot as applyInputSnapshotImpl, getInputUndoStack as getInputUndoStackImpl, readInputSnapshot as readInputSnapshotImpl, } from "./widgetRenderer/inputEditing.js";
66
58
  import { invokeOverlayShortcutTarget as invokeOverlayShortcutTargetImpl, rebuildOverlayShortcutBindings as rebuildOverlayShortcutBindingsImpl, registerOverlayShortcut as registerOverlayShortcutImpl, routeOverlayShortcut as routeOverlayShortcutImpl, selectCommandPaletteShortcutItem as selectCommandPaletteShortcutItemImpl, selectDropdownShortcutItem as selectDropdownShortcutItemImpl, } from "./widgetRenderer/overlayShortcuts.js";
67
- import { rebuildRenderCaches, } from "./widgetRenderer/renderCaches.js";
59
+ import { cleanupRoutingStateAfterRebuild, finalizeLayoutOnlyOverlayState, finalizeRebuiltOverlayState, rebuildOverlayStateForLayout, rebuildRoutingWidgetMapsAndOverlayState, } from "./widgetRenderer/overlayState.js";
60
+ import { routeEngineEventImpl, } from "./widgetRenderer/routeEngineEvent.js";
68
61
  import { buildLayoutRectIndexes, updateLayoutStabilitySignatures, } from "./widgetRenderer/submitFramePipeline.js";
69
- import { routeToolApprovalDialogKeyDown } from "./widgetRenderer/toolApprovalRouting.js";
70
- const UTF8_DECODER = new TextDecoder();
71
62
  const UTF8_ENCODER = new TextEncoder();
72
63
  const BASE64_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
73
64
  function encodeBase64(bytes) {
@@ -109,60 +100,11 @@ function describeThrown(v) {
109
100
  return "[unstringifiable thrown value]";
110
101
  }
111
102
  }
112
- function invokeCallbackSafely(callback, ...args) {
113
- if (typeof callback !== "function")
114
- return false;
115
- try {
116
- callback(...args);
117
- return true;
118
- }
119
- catch (e) {
120
- if (DEV_MODE) {
121
- const message = describeThrown(e);
122
- warnDev(`[rezi] widget callback threw: ${message}`);
123
- }
124
- return false;
125
- }
126
- }
127
103
  function isI32NonNegative(n) {
128
104
  return Number.isInteger(n) && n >= 0 && n <= 2147483647;
129
105
  }
130
- const LAYER_ZINDEX_SCALE = 1_000_000;
131
- const LAYER_ZINDEX_MAX_BASE = Math.floor((Number.MAX_SAFE_INTEGER - (LAYER_ZINDEX_SCALE - 1)) / LAYER_ZINDEX_SCALE);
132
- function clampInt(v, min, max) {
133
- if (v < min)
134
- return min;
135
- if (v > max)
136
- return max;
137
- return v;
138
- }
139
- function clampIndexScrollTopForRows(scrollTop, totalRows, viewportRows) {
140
- const maxScrollTop = Math.max(0, totalRows - viewportRows);
141
- if (!Number.isFinite(scrollTop) || scrollTop <= 0)
142
- return 0;
143
- if (scrollTop >= maxScrollTop)
144
- return maxScrollTop;
145
- return Math.trunc(scrollTop);
146
- }
147
- function encodeLayerZIndex(baseZ, overlaySeq) {
148
- if (baseZ === null)
149
- return overlaySeq;
150
- const clampedBaseZ = clampInt(baseZ, -LAYER_ZINDEX_MAX_BASE, LAYER_ZINDEX_MAX_BASE);
151
- return clampedBaseZ * LAYER_ZINDEX_SCALE + overlaySeq;
152
- }
153
- const EMPTY_ROUTING = Object.freeze({});
154
106
  const EMPTY_STRING_ARRAY = Object.freeze([]);
155
107
  const EMPTY_INSTANCE_ID_ARRAY = Object.freeze([]);
156
- const CONSTRAINT_NODE_PROPS = Object.freeze([
157
- "width",
158
- "height",
159
- "minWidth",
160
- "maxWidth",
161
- "minHeight",
162
- "maxHeight",
163
- "flexBasis",
164
- "display",
165
- ]);
166
108
  const CONSTRAINT_RESOLUTION_NONE = Object.freeze({ kind: "none" });
167
109
  const CONSTRAINT_RESOLUTION_REUSED = Object.freeze({ kind: "reused" });
168
110
  const CONSTRAINT_RESOLUTION_CACHE_HIT = Object.freeze({ kind: "cacheHit" });
@@ -177,15 +119,7 @@ const EMPTY_CONSTRAINT_BREADCRUMBS = Object.freeze({
177
119
  hiddenInstanceCount: 0,
178
120
  focused: null,
179
121
  });
180
- const ROUTE_RENDER = Object.freeze({ needsRender: true });
181
- const ROUTE_NO_RENDER = Object.freeze({ needsRender: false });
182
- const ROUTE_NO_RENDER_CONSUMED = Object.freeze({
183
- needsRender: false,
184
- consumed: true,
185
- });
186
122
  const ZERO_RECT = Object.freeze({ x: 0, y: 0, w: 0, h: 0 });
187
- const INCREMENTAL_DAMAGE_AREA_FRACTION = 0.45;
188
- const DEFAULT_POSITION_TRANSITION_DURATION_MS = 180;
189
123
  const EMPTY_FOCUS_ERRORS = Object.freeze([]);
190
124
  const EMPTY_FOCUS_INFO = Object.freeze({
191
125
  id: null,
@@ -223,33 +157,6 @@ function readLayoutShapeIdentity(vnode) {
223
157
  return `key:${key}`;
224
158
  return null;
225
159
  }
226
- function clipRectToViewport(rect, viewport) {
227
- const x0 = Math.max(0, rect.x);
228
- const y0 = Math.max(0, rect.y);
229
- const x1 = Math.min(viewport.cols, rect.x + rect.w);
230
- const y1 = Math.min(viewport.rows, rect.y + rect.h);
231
- const w = x1 - x0;
232
- const h = y1 - y0;
233
- if (w <= 0 || h <= 0)
234
- return null;
235
- return { x: x0, y: y0, w, h };
236
- }
237
- function rectOverlapsOrTouches(a, b) {
238
- return a.x <= b.x + b.w && a.x + a.w >= b.x && a.y <= b.y + b.h && a.y + a.h >= b.y;
239
- }
240
- function unionRect(a, b) {
241
- const x0 = Math.min(a.x, b.x);
242
- const y0 = Math.min(a.y, b.y);
243
- const x1 = Math.max(a.x + a.w, b.x + b.w);
244
- const y1 = Math.max(a.y + a.h, b.y + b.h);
245
- return { x: x0, y: y0, w: x1 - x0, h: y1 - y0 };
246
- }
247
- function isNonEmptyRect(rect) {
248
- return rect !== undefined && rect.w > 0 && rect.h > 0;
249
- }
250
- function rectEquals(a, b) {
251
- return a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;
252
- }
253
160
  function monotonicNowMs() {
254
161
  const perf = globalThis.performance;
255
162
  const perfNow = perf?.now;
@@ -533,19 +440,6 @@ function hasRuntimeLayoutShapeMismatch(root, layoutRoot) {
533
440
  }
534
441
  return runtimeStack.length !== layoutStack.length;
535
442
  }
536
- function cloneFocusManagerState(state) {
537
- return Object.freeze({
538
- focusedId: state.focusedId,
539
- activeZoneId: state.activeZoneId,
540
- ...(state.pendingFocusedId === undefined ? {} : { pendingFocusedId: state.pendingFocusedId }),
541
- zones: new Map(state.zones),
542
- trapStack: Object.freeze([...state.trapStack]),
543
- ...(state.trapReturnFocusById === undefined
544
- ? {}
545
- : { trapReturnFocusById: new Map(state.trapReturnFocusById) }),
546
- lastFocusedByZone: new Map(state.lastFocusedByZone),
547
- });
548
- }
549
443
  /**
550
444
  * Renderer for widget view mode.
551
445
  *
@@ -682,6 +576,7 @@ export class WidgetRenderer {
682
576
  onCloseByLayerId = new Map();
683
577
  dropdownStack = Object.freeze([]);
684
578
  dropdownSelectedIndexById = new Map();
579
+ dropdownWindowStartById = new Map();
685
580
  overlayShortcutOwners = Object.freeze([]);
686
581
  overlayShortcutBySequence = new Map();
687
582
  overlayShortcutTrie = buildTrie(Object.freeze([]));
@@ -1048,7 +943,7 @@ export class WidgetRenderer {
1048
943
  if (this.exitRenderNodeByInstanceId.size === 0)
1049
944
  return;
1050
945
  for (const exitNode of this.exitRenderNodeByInstanceId.values()) {
1051
- renderTree(this.builder, this.focusState, exitNode.layoutRoot, this._pooledRectById, viewport, theme, tick, DEFAULT_BASE_STYLE, exitNode.runtimeRoot, this.exitAnimatedRectByInstanceId, this.exitAnimatedOpacityByInstanceId, cursorInfo, this.virtualListStore, this.tableStore, this.treeStore, this.loadedTreeChildrenByTreeId, this.commandPaletteItemsById, this.commandPaletteLoadingById, this.toolApprovalFocusedActionById, this.dropdownSelectedIndexById, this.diffViewerFocusedHunkById, this.diffViewerExpandedHunksById, this.tableRenderCacheById, this.logsConsoleRenderCacheById, this.diffRenderCacheById, this.codeEditorRenderCacheById, focusAnnouncement, undefined, this.terminalProfile, this.pressedId);
946
+ renderTree(this.builder, this.focusState, exitNode.layoutRoot, this._pooledRectById, viewport, theme, tick, DEFAULT_BASE_STYLE, exitNode.runtimeRoot, this.exitAnimatedRectByInstanceId, this.exitAnimatedOpacityByInstanceId, cursorInfo, this.virtualListStore, this.tableStore, this.treeStore, this.loadedTreeChildrenByTreeId, this.commandPaletteItemsById, this.commandPaletteLoadingById, this.toolApprovalFocusedActionById, this.dropdownSelectedIndexById, this.dropdownWindowStartById, this.diffViewerFocusedHunkById, this.diffViewerExpandedHunksById, this.tableRenderCacheById, this.logsConsoleRenderCacheById, this.diffRenderCacheById, this.codeEditorRenderCacheById, focusAnnouncement, undefined, this.terminalProfile, this.pressedId);
1052
947
  }
1053
948
  }
1054
949
  /**
@@ -1060,17 +955,7 @@ export class WidgetRenderer {
1060
955
  return this.focusState.focusedId;
1061
956
  }
1062
957
  buildFallbackFocusInfo(id) {
1063
- const toastActionLabel = this.toastActionLabelByFocusId.get(id) ?? null;
1064
- const primary = toastActionLabel ?? id;
1065
- return Object.freeze({
1066
- id,
1067
- kind: null,
1068
- accessibleLabel: toastActionLabel,
1069
- visibleLabel: toastActionLabel,
1070
- required: false,
1071
- errors: EMPTY_FOCUS_ERRORS,
1072
- announcement: primary,
1073
- });
958
+ return buildFallbackFocusInfoImpl({ toastActionLabelByFocusId: this.toastActionLabelByFocusId }, id);
1074
959
  }
1075
960
  /**
1076
961
  * Get structured focus semantics for the currently focused widget.
@@ -1091,29 +976,21 @@ export class WidgetRenderer {
1091
976
  * Capture the current focus/routing metadata for app-level route restoration.
1092
977
  */
1093
978
  captureFocusSnapshot() {
1094
- return Object.freeze({
1095
- focusState: cloneFocusManagerState(this.focusState),
1096
- focusList: Object.freeze([...this.focusList]),
1097
- baseFocusList: Object.freeze([...this.baseFocusList]),
1098
- enabledById: new Map(this.enabledById),
1099
- baseEnabledById: new Map(this.baseEnabledById),
1100
- pressableIds: new Set(this.pressableIds),
1101
- traps: new Map(this.traps),
1102
- zoneMetaById: new Map(this.zoneMetaById),
1103
- });
979
+ return captureFocusSnapshotState(this.focusState, this.focusList, this.baseFocusList, this.enabledById, this.baseEnabledById, this.pressableIds, this.traps, this.zoneMetaById);
1104
980
  }
1105
981
  /**
1106
982
  * Restore a previously captured focus snapshot.
1107
983
  */
1108
984
  restoreFocusSnapshot(snapshot) {
1109
- this.focusState = cloneFocusManagerState(snapshot.focusState);
1110
- this.focusList = Object.freeze([...snapshot.focusList]);
1111
- this.baseFocusList = Object.freeze([...snapshot.baseFocusList]);
1112
- this.enabledById = new Map(snapshot.enabledById);
1113
- this.baseEnabledById = new Map(snapshot.baseEnabledById);
1114
- this.pressableIds = new Set(snapshot.pressableIds);
1115
- this.traps = new Map(snapshot.traps);
1116
- this.zoneMetaById = new Map(snapshot.zoneMetaById);
985
+ const restored = restoreFocusSnapshotState(snapshot);
986
+ this.focusState = restored.focusState;
987
+ this.focusList = restored.focusList;
988
+ this.baseFocusList = restored.baseFocusList;
989
+ this.enabledById = restored.enabledById;
990
+ this.baseEnabledById = restored.baseEnabledById;
991
+ this.pressableIds = restored.pressableIds;
992
+ this.traps = restored.traps;
993
+ this.zoneMetaById = restored.zoneMetaById;
1117
994
  }
1118
995
  /**
1119
996
  * Get the latest committed id->rect layout index.
@@ -1224,531 +1101,119 @@ export class WidgetRenderer {
1224
1101
  * @returns Routing outcome with render flag and optional action
1225
1102
  */
1226
1103
  routeEngineEvent(event) {
1227
- if (!this.committedRoot || !this.layoutTree)
1228
- return ROUTE_NO_RENDER;
1229
- const enabledById = this.enabledById;
1230
- const prevFocusedId = this.focusState.focusedId;
1231
- const prevActiveZoneId = this.focusState.activeZoneId;
1232
- const prevPressedId = this.pressedId;
1233
- const focusedId = this.focusState.focusedId;
1234
- const mouseTargetId = event.kind === "mouse"
1235
- ? hitTestFocusable(this.committedRoot.vnode, this.layoutTree, event.x, event.y)
1236
- : null;
1237
- const mouseTargetAnyId = event.kind === "mouse" ? hitTestAnyId(this.layoutTree, event.x, event.y) : null;
1238
- let localNeedsRender = false;
1239
- // Overlay routing: dropdown key navigation, layer/modal ESC close, and modal backdrop blocking.
1240
- if (event.kind === "key" && event.action === "down") {
1241
- const shortcutResult = this.routeOverlayShortcut(event);
1242
- if (shortcutResult === "matched")
1243
- return ROUTE_RENDER;
1244
- if (shortcutResult === "pending")
1245
- return ROUTE_NO_RENDER_CONSUMED;
1246
- const topLayerId = this.layerStack.length > 0 ? (this.layerStack[this.layerStack.length - 1] ?? null) : null;
1247
- const topDropdownId = this.dropdownStack.length > 0
1248
- ? (this.dropdownStack[this.dropdownStack.length - 1] ?? null)
1249
- : null;
1250
- if (topDropdownId && topLayerId === `dropdown:${topDropdownId}`) {
1251
- const dropdown = this.dropdownById.get(topDropdownId);
1252
- if (dropdown) {
1253
- const selectedIndex = this.dropdownSelectedIndexById.get(topDropdownId) ?? 0;
1254
- const ctx = {
1255
- dropdownId: topDropdownId,
1256
- items: dropdown.items,
1257
- selectedIndex,
1258
- ...(dropdown.onSelect ? { onSelect: dropdown.onSelect } : {}),
1259
- ...(dropdown.onClose ? { onClose: dropdown.onClose } : {}),
1260
- };
1261
- const r = routeDropdownKey(event, ctx);
1262
- if (r.nextSelectedIndex !== undefined) {
1263
- this.dropdownSelectedIndexById.set(topDropdownId, r.nextSelectedIndex);
1264
- }
1265
- if (r.consumed)
1266
- return ROUTE_RENDER;
1267
- }
1268
- }
1269
- const layerRes = routeLayerEscape(event, {
1270
- layerStack: this.layerStack,
1271
- closeOnEscape: this.closeOnEscapeByLayerId,
1272
- onClose: this.onCloseByLayerId,
1273
- });
1274
- if (layerRes.consumed)
1275
- return ROUTE_RENDER;
1276
- }
1277
- if (event.kind === "mouse") {
1278
- const dropdownMouse = routeDropdownMouse(event, {
1279
- layerStack: this.layerStack,
1280
- dropdownStack: this.dropdownStack,
1281
- dropdownById: this.dropdownById,
1282
- dropdownSelectedIndexById: this.dropdownSelectedIndexById,
1283
- pressedDropdown: this.pressedDropdown,
1284
- setPressedDropdown: (next) => {
1285
- this.pressedDropdown = next;
1286
- },
1287
- computeDropdownRect: (props) => this.computeDropdownRect(props),
1288
- });
1289
- if (dropdownMouse)
1290
- return dropdownMouse;
1291
- const layerBackdrop = routeLayerBackdropMouse(event, {
1292
- layerRegistry: this.layerRegistry,
1293
- closeOnBackdropByLayerId: this.closeOnBackdropByLayerId,
1294
- onCloseByLayerId: this.onCloseByLayerId,
1295
- });
1296
- if (layerBackdrop)
1297
- return layerBackdrop;
1298
- }
1299
- const splitPaneRouting = routeSplitPaneMouse(event, {
1104
+ const state = {
1105
+ focusState: this.focusState,
1106
+ pressedId: this.pressedId,
1107
+ pressedDropdown: this.pressedDropdown,
1108
+ pressedVirtualList: this.pressedVirtualList,
1109
+ pressedTable: this.pressedTable,
1110
+ pressedTableHeader: this.pressedTableHeader,
1111
+ lastTableClick: this.lastTableClick,
1112
+ pressedFileTree: this.pressedFileTree,
1113
+ lastFileTreeClick: this.lastFileTreeClick,
1114
+ pressedFilePicker: this.pressedFilePicker,
1115
+ lastFilePickerClick: this.lastFilePickerClick,
1116
+ pressedTree: this.pressedTree,
1117
+ lastTreeClick: this.lastTreeClick,
1300
1118
  splitPaneDrag: this.splitPaneDrag,
1301
- setSplitPaneDrag: (next) => {
1302
- this.splitPaneDrag = next;
1303
- },
1304
1119
  splitPaneLastDividerDown: this.splitPaneLastDividerDown,
1305
- setSplitPaneLastDividerDown: (next) => {
1306
- this.splitPaneLastDividerDown = next;
1307
- },
1308
- splitPaneById: this.splitPaneById,
1309
- splitPaneChildRectsById: this.splitPaneChildRectsById,
1310
- rectById: this.rectById,
1311
- });
1312
- if (splitPaneRouting)
1313
- return splitPaneRouting;
1314
- const toastMouse = routeToastMouseDown(event, {
1315
- toastContainers: this.toastContainers,
1316
- focusState: this.focusState,
1317
- setFocusState: (next) => {
1318
- this.focusState = next;
1319
- },
1120
+ };
1121
+ const outcome = routeEngineEventImpl(event, {
1122
+ committedRoot: this.committedRoot,
1123
+ layoutTree: this.layoutTree,
1124
+ enabledById: this.enabledById,
1125
+ focusList: this.focusList,
1126
+ pressableIds: this.pressableIds,
1127
+ traps: this.traps,
1320
1128
  zoneMetaById: this.zoneMetaById,
1321
- invokeFocusZoneCallbacks: (prevZoneId, nextZoneId, prevZones, nextZones) => this.invokeFocusZoneCallbacks(prevZoneId, nextZoneId, prevZones, nextZones),
1322
- }, prevActiveZoneId);
1323
- if (toastMouse)
1324
- return toastMouse;
1325
- // Route complex widgets first (so arrow keys act "within" the widget, not as focus movement).
1326
- if (event.kind === "key" && event.action === "down" && focusedId !== null) {
1327
- const toastActionRoute = routeToastActionKeyDown(event, {
1328
- focusedId,
1329
- toastActionByFocusId: this.toastActionByFocusId,
1330
- });
1331
- if (toastActionRoute)
1332
- return toastActionRoute;
1333
- // Command palette routing (GitHub issue #136)
1334
- const palette = this.commandPaletteById.get(focusedId);
1335
- if (palette?.open === true) {
1336
- const items = this.commandPaletteItemsById.get(palette.id) ?? Object.freeze([]);
1337
- if (routeCommandPaletteKeyDown(event, palette, items)) {
1338
- return ROUTE_RENDER;
1339
- }
1340
- }
1341
- // Tool approval dialog routing (GitHub issue #136)
1342
- const toolDialog = this.toolApprovalDialogById.get(focusedId);
1343
- if (toolDialog?.open === true) {
1344
- if (routeToolApprovalDialogKeyDown(event, toolDialog, this.toolApprovalFocusedActionById)) {
1345
- return ROUTE_RENDER;
1346
- }
1347
- }
1348
- // File tree explorer routing (GitHub issue #136)
1349
- const fte = this.fileTreeExplorerById.get(focusedId);
1350
- if (fte) {
1351
- if (routeFileTreeExplorerKeyDown(event, fte, this.treeStore)) {
1352
- return ROUTE_RENDER;
1353
- }
1354
- }
1355
- // File picker routing (GitHub issue #136)
1356
- const fp = this.filePickerById.get(focusedId);
1357
- if (fp) {
1358
- if (routeFilePickerKeyDown(event, fp, this.treeStore)) {
1359
- return ROUTE_RENDER;
1360
- }
1361
- }
1362
- // Code editor routing (GitHub issue #136)
1363
- const editor = this.codeEditorById.get(focusedId);
1364
- if (editor) {
1365
- const isCtrl = (event.mods & ZR_MOD_CTRL) !== 0;
1366
- const isCopy = event.key === 67;
1367
- const isCut = event.key === 88;
1368
- const selection = editor.selection;
1369
- const hasSelection = selection !== null &&
1370
- (selection.anchor.line !== selection.active.line ||
1371
- selection.anchor.column !== selection.active.column);
1372
- if (isCtrl && hasSelection && (isCopy || isCut)) {
1373
- const selected = selection ? getSelectedText(editor.lines, selection) : "";
1374
- if (selected.length > 0)
1375
- this.writeSelectedTextToClipboard(selected);
1376
- if (isCut && editor.readOnly !== true) {
1377
- const cut = selection ? deleteRange(editor.lines, selection) : null;
1378
- if (!cut)
1379
- return ROUTE_NO_RENDER_CONSUMED;
1380
- editor.onSelectionChange(null);
1381
- editor.onChange(cut.lines, cut.cursor);
1382
- return ROUTE_RENDER;
1383
- }
1384
- return ROUTE_NO_RENDER_CONSUMED;
1385
- }
1386
- const rect = this.rectById.get(editor.id) ?? null;
1387
- const r = routeCodeEditorKeyDown(event, editor, rect);
1388
- if (r)
1389
- return r;
1390
- }
1391
- const logsRoute = routeLogsConsoleKeyDown(event, {
1392
- focusedId,
1393
- logsConsoleById: this.logsConsoleById,
1394
- rectById: this.rectById,
1395
- logsConsoleRenderCacheById: this.logsConsoleRenderCacheById,
1396
- logsConsoleLastGTimeById: this.logsConsoleLastGTimeById,
1397
- });
1398
- if (logsRoute)
1399
- return logsRoute;
1400
- const diffRoute = routeDiffViewerKeyDown(event, {
1401
- focusedId,
1402
- diffViewerById: this.diffViewerById,
1403
- diffViewerFocusedHunkById: this.diffViewerFocusedHunkById,
1404
- diffViewerExpandedHunksById: this.diffViewerExpandedHunksById,
1405
- });
1406
- if (diffRoute)
1407
- return diffRoute;
1408
- const virtualListRoute = routeVirtualListKeyDown(event, {
1409
- focusedId,
1410
- virtualListById: this.virtualListById,
1411
- virtualListStore: this.virtualListStore,
1412
- });
1413
- if (virtualListRoute)
1414
- return virtualListRoute;
1415
- const tableRoute = routeTableKeyDown(event, {
1416
- focusedId,
1417
- tableById: this.tableById,
1418
- tableRenderCacheById: this.tableRenderCacheById,
1419
- tableStore: this.tableStore,
1420
- emptyStringArray: EMPTY_STRING_ARRAY,
1421
- });
1422
- if (tableRoute)
1423
- return tableRoute;
1424
- const treeRoute = routeTreeKeyDown(event, {
1425
- focusedId,
1426
- treeById: this.treeById,
1427
- treeStore: this.treeStore,
1428
- loadedTreeChildrenByTreeId: this.loadedTreeChildrenByTreeId,
1429
- treeLoadTokenByTreeAndKey: this.treeLoadTokenByTreeAndKey,
1430
- allocNextTreeLoadToken: () => this.nextTreeLoadToken++,
1431
- requestRender: this.requestRender,
1432
- });
1433
- if (treeRoute)
1434
- return treeRoute;
1435
- const sliderRoute = routeSliderKeyDown(event, {
1436
- focusedId,
1437
- sliderById: this.sliderById,
1438
- });
1439
- if (sliderRoute)
1440
- return sliderRoute;
1441
- const selectRoute = routeSelectKeyDown(event, {
1442
- focusedId,
1443
- selectById: this.selectById,
1444
- });
1445
- if (selectRoute)
1446
- return selectRoute;
1447
- const checkboxRoute = routeCheckboxKeyDown(event, {
1448
- focusedId,
1449
- checkboxById: this.checkboxById,
1450
- });
1451
- if (checkboxRoute)
1452
- return checkboxRoute;
1453
- const radioGroupRoute = routeRadioGroupKeyDown(event, {
1454
- focusedId,
1455
- radioGroupById: this.radioGroupById,
1456
- });
1457
- if (radioGroupRoute)
1458
- return radioGroupRoute;
1459
- }
1460
- const wheelRoute = routeMouseWheel(event, {
1461
- layerRegistry: this.layerRegistry,
1462
- layerStack: this.layerStack,
1463
- mouseTargetId,
1464
- mouseTargetAnyId,
1465
- focusedId,
1129
+ inputById: this.inputById,
1130
+ buttonById: this.buttonById,
1131
+ linkById: this.linkById,
1466
1132
  virtualListById: this.virtualListById,
1467
- virtualListStore: this.virtualListStore,
1133
+ tableById: this.tableById,
1134
+ treeById: this.treeById,
1135
+ dropdownById: this.dropdownById,
1136
+ sliderById: this.sliderById,
1137
+ selectById: this.selectById,
1138
+ checkboxById: this.checkboxById,
1139
+ radioGroupById: this.radioGroupById,
1140
+ commandPaletteById: this.commandPaletteById,
1141
+ commandPaletteItemsById: this.commandPaletteItemsById,
1142
+ filePickerById: this.filePickerById,
1143
+ fileTreeExplorerById: this.fileTreeExplorerById,
1144
+ splitPaneById: this.splitPaneById,
1468
1145
  codeEditorById: this.codeEditorById,
1469
- codeEditorRenderCacheById: this.codeEditorRenderCacheById,
1470
- logsConsoleById: this.logsConsoleById,
1471
- logsConsoleRenderCacheById: this.logsConsoleRenderCacheById,
1472
1146
  diffViewerById: this.diffViewerById,
1147
+ toolApprovalDialogById: this.toolApprovalDialogById,
1148
+ logsConsoleById: this.logsConsoleById,
1473
1149
  rectById: this.rectById,
1474
- scrollOverrides: this.scrollOverrides,
1475
- findScrollableAncestors: (targetId) => this.findScrollableAncestors(targetId),
1476
- });
1477
- if (wheelRoute)
1478
- return wheelRoute;
1479
- // Text/paste input for command palette and code editor (docs/18 text events are distinct from keys).
1480
- if ((event.kind === "text" || event.kind === "paste") && this.focusState.focusedId !== null) {
1481
- const focusedId = this.focusState.focusedId;
1482
- const palette = this.commandPaletteById.get(focusedId);
1483
- if (palette?.open === true) {
1484
- const append = event.kind === "text"
1485
- ? event.codepoint >= 0 && event.codepoint <= 0x10ffff
1486
- ? String.fromCodePoint(event.codepoint)
1487
- : ""
1488
- : UTF8_DECODER.decode(event.bytes);
1489
- if (append.length > 0) {
1490
- palette.onChange(palette.query + append);
1491
- palette.onSelectionChange?.(0);
1492
- return ROUTE_RENDER;
1493
- }
1494
- }
1495
- const editor = this.codeEditorById.get(focusedId);
1496
- if (editor && editor.readOnly !== true) {
1497
- const insert = event.kind === "text"
1498
- ? event.codepoint >= 0 && event.codepoint <= 0x10ffff
1499
- ? String.fromCodePoint(event.codepoint)
1500
- : ""
1501
- : UTF8_DECODER.decode(event.bytes);
1502
- if (insert.length > 0) {
1503
- const base = editor.selection ? deleteRange(editor.lines, editor.selection) : null;
1504
- const next = insertText(base ? base.lines : editor.lines, base ? base.cursor : editor.cursor, insert);
1505
- if (editor.selection !== null)
1506
- editor.onSelectionChange(null);
1507
- editor.onChange(next.lines, next.cursor);
1508
- return ROUTE_RENDER;
1509
- }
1510
- }
1511
- }
1512
- localNeedsRender =
1513
- routeVirtualListMouseClick(event, {
1514
- mouseTargetId,
1515
- virtualListById: this.virtualListById,
1516
- rectById: this.rectById,
1517
- virtualListStore: this.virtualListStore,
1518
- pressedVirtualList: this.pressedVirtualList,
1519
- setPressedVirtualList: (next) => {
1520
- this.pressedVirtualList = next;
1521
- },
1522
- }) || localNeedsRender;
1523
- localNeedsRender =
1524
- routeTableMouseClick(event, {
1525
- mouseTargetId,
1526
- tableById: this.tableById,
1527
- rectById: this.rectById,
1528
- tableRenderCacheById: this.tableRenderCacheById,
1529
- tableStore: this.tableStore,
1530
- pressedTable: this.pressedTable,
1531
- setPressedTable: (next) => {
1532
- this.pressedTable = next;
1533
- },
1534
- pressedTableHeader: this.pressedTableHeader,
1535
- setPressedTableHeader: (next) => {
1536
- this.pressedTableHeader = next;
1537
- },
1538
- lastTableClick: this.lastTableClick,
1539
- setLastTableClick: (next) => {
1540
- this.lastTableClick = next;
1541
- },
1542
- emptyStringArray: EMPTY_STRING_ARRAY,
1543
- }) || localNeedsRender;
1544
- localNeedsRender =
1545
- routeFilePickerMouseClick(event, {
1546
- mouseTargetId,
1547
- filePickerById: this.filePickerById,
1548
- rectById: this.rectById,
1549
- treeStore: this.treeStore,
1550
- pressedFilePicker: this.pressedFilePicker,
1551
- setPressedFilePicker: (next) => {
1552
- this.pressedFilePicker = next;
1553
- },
1554
- lastFilePickerClick: this.lastFilePickerClick,
1555
- setLastFilePickerClick: (next) => {
1556
- this.lastFilePickerClick = next;
1557
- },
1558
- }) || localNeedsRender;
1559
- localNeedsRender =
1560
- routeFileTreeExplorerMouseClick(event, {
1561
- mouseTargetId,
1562
- fileTreeExplorerById: this.fileTreeExplorerById,
1563
- rectById: this.rectById,
1564
- treeStore: this.treeStore,
1565
- pressedFileTree: this.pressedFileTree,
1566
- setPressedFileTree: (next) => {
1567
- this.pressedFileTree = next;
1568
- },
1569
- lastFileTreeClick: this.lastFileTreeClick,
1570
- setLastFileTreeClick: (next) => {
1571
- this.lastFileTreeClick = next;
1572
- },
1573
- }) || localNeedsRender;
1574
- localNeedsRender =
1575
- routeTreeMouseClick(event, {
1576
- mouseTargetId,
1577
- treeById: this.treeById,
1578
- rectById: this.rectById,
1579
- treeStore: this.treeStore,
1580
- loadedTreeChildrenByTreeId: this.loadedTreeChildrenByTreeId,
1581
- pressedTree: this.pressedTree,
1582
- setPressedTree: (next) => {
1583
- this.pressedTree = next;
1584
- },
1585
- lastTreeClick: this.lastTreeClick,
1586
- setLastTreeClick: (next) => {
1587
- this.lastTreeClick = next;
1588
- },
1589
- }) || localNeedsRender;
1590
- localNeedsRender =
1591
- routeFileTreeExplorerContextMenuMouse(event, {
1592
- mouseTargetId,
1593
- fileTreeExplorerById: this.fileTreeExplorerById,
1594
- rectById: this.rectById,
1595
- treeStore: this.treeStore,
1596
- }) || localNeedsRender;
1597
- const res = event.kind === "key"
1598
- ? routeKeyWithZones(event, {
1599
- focusedId: this.focusState.focusedId,
1600
- activeZoneId: this.focusState.activeZoneId,
1601
- focusList: this.focusList,
1602
- zones: this.focusState.zones,
1603
- lastFocusedByZone: this.focusState.lastFocusedByZone,
1604
- traps: this.traps,
1605
- trapStack: this.focusState.trapStack,
1606
- enabledById,
1607
- pressableIds: this.pressableIds,
1608
- })
1609
- : event.kind === "mouse"
1610
- ? routeMouse(event, {
1611
- pressedId: this.pressedId,
1612
- hitTestTargetId: mouseTargetId,
1613
- enabledById,
1614
- pressableIds: this.pressableIds,
1615
- })
1616
- : EMPTY_ROUTING;
1617
- if (res.nextPressedId !== undefined)
1618
- this.pressedId = res.nextPressedId;
1619
- if (res.nextZoneId !== undefined) {
1620
- this.focusState = Object.freeze({ ...this.focusState, activeZoneId: res.nextZoneId ?? null });
1621
- }
1622
- if (res.nextFocusedId !== undefined) {
1623
- const nextFocused = res.nextFocusedId;
1624
- let nextZoneId = this.focusState.activeZoneId;
1625
- if (nextFocused !== null) {
1626
- for (const [zoneId, zone] of this.focusState.zones) {
1627
- if (zone.focusableIds.includes(nextFocused)) {
1628
- nextZoneId = zoneId;
1629
- break;
1630
- }
1631
- }
1632
- }
1633
- const nextLastFocusedByZone = new Map(this.focusState.lastFocusedByZone);
1634
- if (nextFocused !== null && nextZoneId !== null) {
1635
- nextLastFocusedByZone.set(nextZoneId, nextFocused);
1636
- }
1637
- this.focusState = Object.freeze({
1638
- ...this.focusState,
1639
- focusedId: nextFocused,
1640
- activeZoneId: nextZoneId,
1641
- lastFocusedByZone: nextLastFocusedByZone,
1642
- });
1643
- }
1644
- const didFocusChange = this.focusState.focusedId !== prevFocusedId;
1645
- const needsRender = didFocusChange || this.pressedId !== prevPressedId || localNeedsRender;
1646
- if (didFocusChange && prevFocusedId !== null) {
1647
- const prevInput = this.inputById.get(prevFocusedId);
1648
- this.invokeBlurCallbackSafely(prevInput?.onBlur);
1649
- }
1650
- if (this.focusState.activeZoneId !== prevActiveZoneId) {
1651
- this.invokeFocusZoneCallbacks(prevActiveZoneId, this.focusState.activeZoneId, this.zoneMetaById, this.zoneMetaById);
1652
- }
1653
- if (res.action) {
1654
- if (res.action.action === "press") {
1655
- const btn = this.buttonById.get(res.action.id);
1656
- if (btn?.onPress)
1657
- btn.onPress();
1658
- const link = this.linkById.get(res.action.id);
1659
- if (link?.onPress)
1660
- link.onPress();
1661
- }
1662
- return Object.freeze({ needsRender, action: res.action });
1663
- }
1664
- const inputEditingRoute = routeInputEditingEvent(event, {
1665
- focusedId: this.focusState.focusedId,
1666
- enabledById,
1667
- inputById: this.inputById,
1150
+ splitPaneChildRectsById: this.splitPaneChildRectsById,
1151
+ toastContainers: this.toastContainers,
1152
+ toastActionByFocusId: this.toastActionByFocusId,
1153
+ dropdownSelectedIndexById: this.dropdownSelectedIndexById,
1154
+ dropdownWindowStartById: this.dropdownWindowStartById,
1155
+ toolApprovalFocusedActionById: this.toolApprovalFocusedActionById,
1156
+ diffViewerFocusedHunkById: this.diffViewerFocusedHunkById,
1157
+ diffViewerExpandedHunksById: this.diffViewerExpandedHunksById,
1158
+ logsConsoleLastGTimeById: this.logsConsoleLastGTimeById,
1159
+ logsConsoleRenderCacheById: this.logsConsoleRenderCacheById,
1160
+ diffRenderCacheById: this.diffRenderCacheById,
1161
+ codeEditorRenderCacheById: this.codeEditorRenderCacheById,
1162
+ tableRenderCacheById: this.tableRenderCacheById,
1668
1163
  inputCursorByInstanceId: this.inputCursorByInstanceId,
1669
1164
  inputSelectionByInstanceId: this.inputSelectionByInstanceId,
1670
1165
  inputWorkingValueByInstanceId: this.inputWorkingValueByInstanceId,
1671
1166
  inputUndoByInstanceId: this.inputUndoByInstanceId,
1672
- writeSelectedTextToClipboard: (text) => {
1673
- this.writeSelectedTextToClipboard(text);
1674
- },
1675
- onInputCallbackError: (error) => {
1676
- this.reportInputCallbackError("onInput", error);
1677
- },
1678
- });
1679
- if (inputEditingRoute)
1680
- return inputEditingRoute;
1681
- return Object.freeze({ needsRender });
1167
+ virtualListStore: this.virtualListStore,
1168
+ tableStore: this.tableStore,
1169
+ treeStore: this.treeStore,
1170
+ loadedTreeChildrenByTreeId: this.loadedTreeChildrenByTreeId,
1171
+ treeLoadTokenByTreeAndKey: this.treeLoadTokenByTreeAndKey,
1172
+ layerRegistry: this.layerRegistry,
1173
+ layerStack: this.layerStack,
1174
+ closeOnEscapeByLayerId: this.closeOnEscapeByLayerId,
1175
+ closeOnBackdropByLayerId: this.closeOnBackdropByLayerId,
1176
+ onCloseByLayerId: this.onCloseByLayerId,
1177
+ dropdownStack: this.dropdownStack,
1178
+ scrollOverrides: this.scrollOverrides,
1179
+ routeOverlayShortcut: (nextEvent) => this.routeOverlayShortcut(nextEvent),
1180
+ invokeFocusZoneCallbacks: (prevZoneId, nextZoneId, prevZones, nextZones) => this.invokeFocusZoneCallbacks(prevZoneId, nextZoneId, prevZones, nextZones),
1181
+ invokeBlurCallbackSafely: (callback) => this.invokeBlurCallbackSafely(callback),
1182
+ computeDropdownRect: (props) => this.computeDropdownRect(props),
1183
+ findScrollableAncestors: (targetId) => this.findScrollableAncestors(targetId),
1184
+ writeSelectedTextToClipboard: (text) => this.writeSelectedTextToClipboard(text),
1185
+ reportInputCallbackError: (name, error) => this.reportInputCallbackError(name, error),
1186
+ requestRender: this.requestRender,
1187
+ allocNextTreeLoadToken: () => this.nextTreeLoadToken++,
1188
+ }, state);
1189
+ this.focusState = state.focusState;
1190
+ this.pressedId = state.pressedId;
1191
+ this.pressedDropdown = state.pressedDropdown;
1192
+ this.pressedVirtualList = state.pressedVirtualList;
1193
+ this.pressedTable = state.pressedTable;
1194
+ this.pressedTableHeader = state.pressedTableHeader;
1195
+ this.lastTableClick = state.lastTableClick;
1196
+ this.pressedFileTree = state.pressedFileTree;
1197
+ this.lastFileTreeClick = state.lastFileTreeClick;
1198
+ this.pressedFilePicker = state.pressedFilePicker;
1199
+ this.lastFilePickerClick = state.lastFilePickerClick;
1200
+ this.pressedTree = state.pressedTree;
1201
+ this.lastTreeClick = state.lastTreeClick;
1202
+ this.splitPaneDrag = state.splitPaneDrag;
1203
+ this.splitPaneLastDividerDown = state.splitPaneLastDividerDown;
1204
+ return outcome;
1682
1205
  }
1683
1206
  invokeFocusZoneCallbacks(prevZoneId, nextZoneId, prevZones, nextZones) {
1684
- if (prevZoneId === nextZoneId)
1685
- return;
1686
- if (prevZoneId !== null) {
1687
- const prev = prevZones.get(prevZoneId);
1688
- if (prev?.onExit) {
1689
- try {
1690
- prev.onExit();
1691
- }
1692
- catch (error) {
1693
- this.reportFocusZoneCallbackError("onExit", error);
1694
- }
1695
- }
1696
- }
1697
- if (nextZoneId !== null) {
1698
- const next = nextZones.get(nextZoneId);
1699
- if (next?.onEnter) {
1700
- try {
1701
- next.onEnter();
1702
- }
1703
- catch (error) {
1704
- this.reportFocusZoneCallbackError("onEnter", error);
1705
- }
1706
- }
1707
- }
1207
+ invokeFocusZoneCallbacksImpl({
1208
+ prevZoneId,
1209
+ nextZoneId,
1210
+ prevZones,
1211
+ nextZones,
1212
+ reportFocusZoneCallbackError: (phase, error) => this.reportFocusZoneCallbackError(phase, error),
1213
+ });
1708
1214
  }
1709
1215
  findScrollableAncestors(targetId) {
1710
- if (targetId === null || !this.committedRoot || !this.layoutTree)
1711
- return Object.freeze([]);
1712
- const stack = [
1713
- {
1714
- runtimeNode: this.committedRoot,
1715
- layoutNode: this.layoutTree,
1716
- scrollables: Object.freeze([]),
1717
- },
1718
- ];
1719
- while (stack.length > 0) {
1720
- const frame = stack.pop();
1721
- if (!frame)
1722
- continue;
1723
- const runtimeNode = frame.runtimeNode;
1724
- const layoutNode = frame.layoutNode;
1725
- let scrollables = frame.scrollables;
1726
- const props = runtimeNode.vnode.props;
1727
- const nodeId = typeof props.id === "string" && props.id.length > 0 ? props.id : null;
1728
- if (nodeId !== null && props.overflow === "scroll" && layoutNode.meta) {
1729
- const meta = layoutNode.meta;
1730
- const hasScrollableAxis = meta.contentWidth > meta.viewportWidth || meta.contentHeight > meta.viewportHeight;
1731
- if (hasScrollableAxis) {
1732
- scrollables = Object.freeze([...scrollables, { nodeId, meta }]);
1733
- }
1734
- }
1735
- if (nodeId === targetId) {
1736
- return Object.freeze([...scrollables].reverse());
1737
- }
1738
- const childCount = Math.min(runtimeNode.children.length, layoutNode.children.length);
1739
- for (let i = childCount - 1; i >= 0; i--) {
1740
- const runtimeChild = runtimeNode.children[i];
1741
- const layoutChild = layoutNode.children[i];
1742
- if (!runtimeChild || !layoutChild)
1743
- continue;
1744
- stack.push({
1745
- runtimeNode: runtimeChild,
1746
- layoutNode: layoutChild,
1747
- scrollables,
1748
- });
1749
- }
1750
- }
1751
- return Object.freeze([]);
1216
+ return findScrollableAncestorsImpl(targetId, this.committedRoot, this.layoutTree);
1752
1217
  }
1753
1218
  applyScrollOverridesToVNode(vnode, overrides = this
1754
1219
  .scrollOverrides) {
@@ -1843,10 +1308,7 @@ export class WidgetRenderer {
1843
1308
  return Object.freeze(nextVNode);
1844
1309
  }
1845
1310
  describeConstraintGraphFatal(fatal) {
1846
- if (fatal.code === "ZRUI_CIRCULAR_CONSTRAINT") {
1847
- return `Circular constraint dependency: ${fatal.cycle.join(" -> ")}`;
1848
- }
1849
- return fatal.detail;
1311
+ return describeConstraintGraphFatalImpl(fatal);
1850
1312
  }
1851
1313
  readWidgetIdFromRuntimeNode(node) {
1852
1314
  const id = node.vnode.props?.id;
@@ -1899,477 +1361,81 @@ export class WidgetRenderer {
1899
1361
  };
1900
1362
  }
1901
1363
  shouldRebuildConstraintGraph(root, prevGraph, removedInstanceIds) {
1902
- if (removedInstanceIds.length > 0) {
1903
- for (const instanceId of removedInstanceIds) {
1904
- if (prevGraph.constrainedInstanceIds.has(instanceId) ||
1905
- prevGraph.instanceIdToWidgetId.has(instanceId)) {
1906
- return true;
1907
- }
1908
- }
1909
- }
1910
- this._pooledConstraintRuntimeStack.length = 0;
1911
- this._pooledConstraintRuntimeStack.push(root);
1912
- while (this._pooledConstraintRuntimeStack.length > 0) {
1913
- const node = this._pooledConstraintRuntimeStack.pop();
1914
- if (!node)
1915
- continue;
1916
- if (!node.dirty)
1917
- continue;
1918
- if (node.selfDirty) {
1919
- const prevWidgetId = prevGraph.instanceIdToWidgetId.get(node.instanceId) ?? null;
1920
- const nextWidgetId = this.readWidgetIdFromRuntimeNode(node);
1921
- if (prevWidgetId !== nextWidgetId) {
1922
- return true;
1923
- }
1924
- const hadConstraintExpr = prevGraph.constrainedInstanceIds.has(node.instanceId);
1925
- if ((hadConstraintExpr || this.hasRuntimeConstraintExpr(node)) &&
1926
- this.hasConstraintSourceDiff(node, prevGraph)) {
1927
- return true;
1928
- }
1929
- }
1930
- for (let i = node.children.length - 1; i >= 0; i--) {
1931
- const child = node.children[i];
1932
- if (!child)
1933
- continue;
1934
- if (!child.dirty)
1935
- continue;
1936
- this._pooledConstraintRuntimeStack.push(child);
1937
- }
1938
- }
1939
- return false;
1364
+ return shouldRebuildConstraintGraphImpl(root, prevGraph, removedInstanceIds, this._pooledConstraintRuntimeStack);
1940
1365
  }
1941
1366
  buildConstraintResolutionInputs(root, graph, rootW, rootH) {
1942
- this._pooledConstraintBaseValues.clear();
1943
- this._pooledConstraintParentValues.clear();
1944
- this._pooledConstraintIntrinsicValues.clear();
1945
- this._pooledConstraintParentByInstanceId.clear();
1946
- this._pooledConstraintRuntimeStack.length = 0;
1947
- this._pooledConstraintParentStack.length = 0;
1948
- this._pooledConstraintAxisStack.length = 0;
1949
- let hasStaticHiddenDisplay = false;
1950
- const requiredInstanceIds = graph.requiredRuntimeInstanceIds;
1951
- const intrinsicInstanceIds = graph.intrinsicRuntimeInstanceIds;
1952
- let remainingRequiredInstanceCount = requiredInstanceIds.size;
1953
- this._pooledConstraintRuntimeStack.push(root);
1954
- this._pooledConstraintParentStack.push(null);
1955
- this._pooledConstraintAxisStack.push("column");
1956
- let head = 0;
1957
- while (head < this._pooledConstraintRuntimeStack.length) {
1958
- const node = this._pooledConstraintRuntimeStack[head];
1959
- const parentInstanceId = this._pooledConstraintParentStack[head] ?? null;
1960
- const axis = this._pooledConstraintAxisStack[head] ?? "column";
1961
- head++;
1962
- if (!node)
1963
- continue;
1964
- this._pooledConstraintParentByInstanceId.set(node.instanceId, parentInstanceId);
1965
- const needsNodeData = requiredInstanceIds.has(node.instanceId);
1966
- if (needsNodeData) {
1967
- remainingRequiredInstanceCount--;
1968
- const parentRect = parentInstanceId === null ? null : this._pooledRectByInstanceId.get(parentInstanceId);
1969
- const parentW = parentRect?.w ?? rootW;
1970
- const parentH = parentRect?.h ?? rootH;
1971
- const displayRaw = node.vnode.props
1972
- ?.display;
1973
- if (displayRaw === false)
1974
- hasStaticHiddenDisplay = true;
1975
- const staticDisplay = displayRaw === false ? 0 : displayRaw === true ? 1 : undefined;
1976
- if (graph.constrainedInstanceIds.has(node.instanceId)) {
1977
- this._pooledConstraintParentValues.set(node.instanceId, {
1978
- w: parentW,
1979
- h: parentH,
1980
- min_w: parentW,
1981
- min_h: parentH,
1982
- });
1983
- }
1984
- const rect = this._pooledRectByInstanceId.get(node.instanceId);
1985
- if (rect) {
1986
- const base = {
1987
- width: rect.w,
1988
- height: rect.h,
1989
- minWidth: rect.w,
1990
- minHeight: rect.h,
1991
- };
1992
- if (staticDisplay !== undefined) {
1993
- base.display = staticDisplay;
1994
- }
1995
- this._pooledConstraintBaseValues.set(node.instanceId, {
1996
- ...base,
1997
- });
1998
- }
1999
- else if (staticDisplay !== undefined) {
2000
- this._pooledConstraintBaseValues.set(node.instanceId, {
2001
- display: staticDisplay,
2002
- });
2003
- }
2004
- if (intrinsicInstanceIds.has(node.instanceId)) {
2005
- const intrinsicValues = this.measureConstraintIntrinsicValues(node, parentW, parentH, axis);
2006
- if (intrinsicValues !== null) {
2007
- this._pooledConstraintIntrinsicValues.set(node.instanceId, intrinsicValues);
2008
- }
2009
- }
2010
- }
2011
- if (remainingRequiredInstanceCount === 0)
2012
- break;
2013
- const childAxis = this.resolveConstraintChildAxis(node, axis);
2014
- for (let i = 0; i < node.children.length; i++) {
2015
- const child = node.children[i];
2016
- if (!child)
2017
- continue;
2018
- this._pooledConstraintRuntimeStack.push(child);
2019
- this._pooledConstraintParentStack.push(node.instanceId);
2020
- this._pooledConstraintAxisStack.push(childAxis);
2021
- }
2022
- }
2023
- this._pooledConstraintRuntimeStack.length = 0;
2024
- this._pooledConstraintParentStack.length = 0;
2025
- this._pooledConstraintAxisStack.length = 0;
2026
- this._constraintHasStaticHiddenDisplay = hasStaticHiddenDisplay;
1367
+ const result = buildConstraintResolutionInputsImpl({
1368
+ root,
1369
+ graph,
1370
+ rootW,
1371
+ rootH,
1372
+ pooledConstraintBaseValues: this._pooledConstraintBaseValues,
1373
+ pooledConstraintParentValues: this._pooledConstraintParentValues,
1374
+ pooledConstraintIntrinsicValues: this._pooledConstraintIntrinsicValues,
1375
+ pooledConstraintParentByInstanceId: this._pooledConstraintParentByInstanceId,
1376
+ pooledRectByInstanceId: this._pooledRectByInstanceId,
1377
+ pooledConstraintRuntimeStack: this._pooledConstraintRuntimeStack,
1378
+ pooledConstraintParentStack: this._pooledConstraintParentStack,
1379
+ pooledConstraintAxisStack: this._pooledConstraintAxisStack,
1380
+ });
1381
+ this._constraintHasStaticHiddenDisplay = result.hasStaticHiddenDisplay;
2027
1382
  }
2028
1383
  rebuildConstraintHiddenState(root, valuesByInstanceId) {
2029
- this._pooledHiddenConstraintInstanceIds.clear();
2030
- this._pooledHiddenConstraintWidgetIds.clear();
2031
- this._pooledConstraintRuntimeStack.length = 0;
2032
- this._pooledConstraintVisibilityStack.length = 0;
2033
- this._pooledConstraintRuntimeStack.push(root);
2034
- this._pooledConstraintVisibilityStack.push(false);
2035
- while (this._pooledConstraintRuntimeStack.length > 0) {
2036
- const node = this._pooledConstraintRuntimeStack.pop();
2037
- const parentHidden = this._pooledConstraintVisibilityStack.pop() ?? false;
2038
- if (!node)
2039
- continue;
2040
- const props = (node.vnode.props ?? {});
2041
- const displayResolved = valuesByInstanceId?.get(node.instanceId)?.display;
2042
- const hiddenByResolved = typeof displayResolved === "number" && Number.isFinite(displayResolved)
2043
- ? displayResolved <= 0
2044
- : false;
2045
- const hiddenByStatic = props.display === false;
2046
- const hidden = parentHidden || hiddenByResolved || hiddenByStatic;
2047
- if (hidden) {
2048
- this._pooledHiddenConstraintInstanceIds.add(node.instanceId);
2049
- const id = props.id;
2050
- if (typeof id === "string" && id.length > 0) {
2051
- this._pooledHiddenConstraintWidgetIds.add(id);
2052
- }
2053
- }
2054
- for (let i = node.children.length - 1; i >= 0; i--) {
2055
- const child = node.children[i];
2056
- if (!child)
2057
- continue;
2058
- this._pooledConstraintRuntimeStack.push(child);
2059
- this._pooledConstraintVisibilityStack.push(hidden);
2060
- }
2061
- }
2062
- this._hiddenConstraintInstanceIds = this._pooledHiddenConstraintInstanceIds;
2063
- this._hiddenConstraintWidgetIds = this._pooledHiddenConstraintWidgetIds;
1384
+ const result = rebuildConstraintHiddenStateImpl(root, valuesByInstanceId, this._pooledConstraintRuntimeStack, this._pooledConstraintVisibilityStack, this._pooledHiddenConstraintInstanceIds, this._pooledHiddenConstraintWidgetIds);
1385
+ this._hiddenConstraintInstanceIds = result.hiddenConstraintInstanceIds;
1386
+ this._hiddenConstraintWidgetIds = result.hiddenConstraintWidgetIds;
2064
1387
  }
2065
1388
  rebuildConstraintAffectedPathSet(graph, hiddenInstanceIds) {
2066
- this._pooledConstraintAffectedPathInstanceIds.clear();
2067
- this._pooledConstraintNodesWithAffectedDescendants.clear();
2068
- const addWithAncestors = (instanceId) => {
2069
- let cursor = instanceId;
2070
- while (cursor !== null) {
2071
- this._pooledConstraintAffectedPathInstanceIds.add(cursor);
2072
- const parentInstanceId = this._pooledConstraintParentByInstanceId.get(cursor) ?? null;
2073
- if (parentInstanceId !== null) {
2074
- this._pooledConstraintNodesWithAffectedDescendants.add(parentInstanceId);
2075
- }
2076
- cursor = parentInstanceId;
2077
- }
2078
- };
2079
- for (const node of graph.nodes) {
2080
- addWithAncestors(node.instanceId);
2081
- }
2082
- for (const instanceId of hiddenInstanceIds) {
2083
- addWithAncestors(instanceId);
2084
- }
2085
- this._constraintAffectedPathInstanceIds = this._pooledConstraintAffectedPathInstanceIds;
2086
- this._constraintNodesWithAffectedDescendants =
2087
- this._pooledConstraintNodesWithAffectedDescendants;
1389
+ const result = rebuildConstraintAffectedPathSetImpl(graph, hiddenInstanceIds, this._pooledConstraintAffectedPathInstanceIds, this._pooledConstraintNodesWithAffectedDescendants, this._pooledConstraintParentByInstanceId);
1390
+ this._constraintAffectedPathInstanceIds = result.constraintAffectedPathInstanceIds;
1391
+ this._constraintNodesWithAffectedDescendants = result.constraintNodesWithAffectedDescendants;
2088
1392
  }
2089
1393
  hasConstraintInputSignatureChange(graph, viewport, rootW, rootH) {
2090
- const signature = this._constraintInputSignature;
2091
- let index = 0;
2092
- let changed = !this._constraintInputSignatureValid;
2093
- const write = (value) => {
2094
- if (!changed && !Object.is(signature[index], value))
2095
- changed = true;
2096
- signature[index] = value;
2097
- index++;
2098
- };
2099
- const writeOrNaN = (value) => {
2100
- write(value === undefined ? Number.NaN : value);
2101
- };
2102
- write(graph.fingerprint);
2103
- write(viewport.cols);
2104
- write(viewport.rows);
2105
- write(rootW);
2106
- write(rootH);
2107
- for (const instanceId of graph.requiredRuntimeInstanceIds) {
2108
- const base = this._pooledConstraintBaseValues.get(instanceId);
2109
- const parent = this._pooledConstraintParentValues.get(instanceId);
2110
- const intrinsic = this._pooledConstraintIntrinsicValues.get(instanceId);
2111
- write(instanceId);
2112
- writeOrNaN(base?.width);
2113
- writeOrNaN(base?.height);
2114
- writeOrNaN(base?.minWidth);
2115
- writeOrNaN(base?.minHeight);
2116
- writeOrNaN(base?.display);
2117
- writeOrNaN(parent?.w);
2118
- writeOrNaN(parent?.h);
2119
- writeOrNaN(parent?.min_w);
2120
- writeOrNaN(parent?.min_h);
2121
- writeOrNaN(intrinsic?.w);
2122
- writeOrNaN(intrinsic?.h);
2123
- writeOrNaN(intrinsic?.min_w);
2124
- writeOrNaN(intrinsic?.min_h);
2125
- }
2126
- if (!changed && signature.length !== index)
2127
- changed = true;
2128
- signature.length = index;
2129
- this._constraintInputSignatureValid = true;
2130
- return changed;
1394
+ const result = hasConstraintInputSignatureChangeImpl({
1395
+ graph,
1396
+ viewport,
1397
+ rootW,
1398
+ rootH,
1399
+ pooledConstraintBaseValues: this._pooledConstraintBaseValues,
1400
+ pooledConstraintParentValues: this._pooledConstraintParentValues,
1401
+ pooledConstraintIntrinsicValues: this._pooledConstraintIntrinsicValues,
1402
+ signature: this._constraintInputSignature,
1403
+ valid: this._constraintInputSignatureValid,
1404
+ });
1405
+ this._constraintInputSignatureValid = result.valid;
1406
+ return result.changed;
2131
1407
  }
2132
1408
  invalidateConstraintInputSignature() {
2133
1409
  this._constraintInputSignatureValid = false;
2134
1410
  this._constraintInputSignature.length = 0;
2135
1411
  }
2136
1412
  computeConstraintInputKey(graph, viewport, rootW, rootH) {
2137
- const parts = [
2138
- String(graph.fingerprint),
2139
- String(viewport.cols),
2140
- String(viewport.rows),
2141
- String(rootW),
2142
- String(rootH),
2143
- ];
2144
- for (const instanceId of graph.requiredRuntimeInstanceIds) {
2145
- const base = this._pooledConstraintBaseValues.get(instanceId);
2146
- const parent = this._pooledConstraintParentValues.get(instanceId);
2147
- const intrinsic = this._pooledConstraintIntrinsicValues.get(instanceId);
2148
- parts.push(String(instanceId), String(base?.width ?? "u"), String(base?.height ?? "u"), String(base?.minWidth ?? "u"), String(base?.minHeight ?? "u"), String(base?.display ?? "u"), String(parent?.w ?? rootW), String(parent?.h ?? rootH), String(parent?.min_w ?? rootW), String(parent?.min_h ?? rootH), String(intrinsic?.w ?? "u"), String(intrinsic?.h ?? "u"), String(intrinsic?.min_w ?? "u"), String(intrinsic?.min_h ?? "u"));
2149
- }
2150
- return parts.join("|");
1413
+ return computeConstraintInputKeyImpl(graph, viewport, rootW, rootH, this._pooledConstraintBaseValues, this._pooledConstraintParentValues, this._pooledConstraintIntrinsicValues);
2151
1414
  }
2152
1415
  rebuildConstraintExprIndex(graph) {
2153
- const mutable = new Map();
2154
- for (const node of graph.nodes) {
2155
- const entry = Object.freeze({ prop: node.prop, source: node.expr.source });
2156
- const bucket = mutable.get(node.instanceId);
2157
- if (bucket)
2158
- bucket.push(entry);
2159
- else
2160
- mutable.set(node.instanceId, [entry]);
2161
- }
2162
- const frozen = new Map();
2163
- for (const [instanceId, list] of mutable.entries()) {
2164
- frozen.set(instanceId, Object.freeze(list.slice()));
2165
- }
2166
- this._constraintExprIndexByInstanceId = frozen;
1416
+ this._constraintExprIndexByInstanceId = rebuildConstraintExprIndexImpl(graph);
2167
1417
  }
2168
1418
  computeConstraintBreadcrumbs() {
2169
- const graph = this._constraintGraph;
2170
- if (graph === null || graph.nodes.length === 0)
2171
- return EMPTY_CONSTRAINT_BREADCRUMBS;
2172
- if (this._constraintExprIndexByInstanceId === null) {
2173
- this.rebuildConstraintExprIndex(graph);
2174
- }
2175
- const focusedId = this.focusState.focusedId;
2176
- const resolvedByInstanceId = this._constraintValuesByInstanceId;
2177
- const hiddenInstanceCount = this._hiddenConstraintInstanceIds.size;
2178
- let focused = null;
2179
- if (focusedId) {
2180
- const instances = graph.idToInstances.get(focusedId) ?? EMPTY_INSTANCE_ID_ARRAY;
2181
- const instanceCount = instances.length;
2182
- const instanceId = instances[0] ?? null;
2183
- const resolved = instanceId !== null ? (resolvedByInstanceId?.get(instanceId) ?? null) : null;
2184
- const expressions = instanceId !== null
2185
- ? (this._constraintExprIndexByInstanceId?.get(instanceId) ?? null)
2186
- : null;
2187
- focused = Object.freeze({
2188
- id: focusedId,
2189
- instanceCount,
2190
- instanceId,
2191
- resolved: resolved
2192
- ? (() => {
2193
- const out = {};
2194
- if (typeof resolved.display === "number" && Number.isFinite(resolved.display))
2195
- out.display = resolved.display;
2196
- if (typeof resolved.width === "number" && Number.isFinite(resolved.width))
2197
- out.width = resolved.width;
2198
- if (typeof resolved.height === "number" && Number.isFinite(resolved.height))
2199
- out.height = resolved.height;
2200
- if (typeof resolved.minWidth === "number" && Number.isFinite(resolved.minWidth))
2201
- out.minWidth = resolved.minWidth;
2202
- if (typeof resolved.maxWidth === "number" && Number.isFinite(resolved.maxWidth))
2203
- out.maxWidth = resolved.maxWidth;
2204
- if (typeof resolved.minHeight === "number" && Number.isFinite(resolved.minHeight))
2205
- out.minHeight = resolved.minHeight;
2206
- if (typeof resolved.maxHeight === "number" && Number.isFinite(resolved.maxHeight))
2207
- out.maxHeight = resolved.maxHeight;
2208
- if (typeof resolved.flexBasis === "number" && Number.isFinite(resolved.flexBasis))
2209
- out.flexBasis = resolved.flexBasis;
2210
- return Object.freeze(out);
2211
- })()
2212
- : null,
2213
- expressions,
2214
- });
2215
- }
2216
- return Object.freeze({
2217
- enabled: true,
2218
- graphFingerprint: graph.fingerprint,
2219
- nodeCount: graph.nodes.length,
2220
- cacheKey: this._constraintLastCacheKey,
2221
- resolution: this._constraintLastResolution,
2222
- hiddenInstanceCount,
2223
- focused,
1419
+ return computeConstraintBreadcrumbsImpl({
1420
+ graph: this._constraintGraph,
1421
+ exprIndexByInstanceId: this._constraintExprIndexByInstanceId,
1422
+ rebuildConstraintExprIndex: (graph) => rebuildConstraintExprIndexImpl(graph),
1423
+ focusedId: this.focusState.focusedId,
1424
+ resolvedByInstanceId: this._constraintValuesByInstanceId,
1425
+ hiddenConstraintInstanceIds: this._hiddenConstraintInstanceIds,
1426
+ lastCacheKey: this._constraintLastCacheKey,
1427
+ lastResolution: this._constraintLastResolution,
1428
+ emptyConstraintBreadcrumbs: EMPTY_CONSTRAINT_BREADCRUMBS,
1429
+ emptyInstanceIds: EMPTY_INSTANCE_ID_ARRAY,
2224
1430
  });
2225
1431
  }
2226
1432
  applyConstraintOverridesToVNode(runtimeNode, valuesByInstanceId, hiddenInstanceIds, affectedPathInstanceIds) {
2227
- const vnode = runtimeNode.vnode;
2228
- const propsRecord = (vnode.props ?? {});
2229
- const resolved = valuesByInstanceId?.get(runtimeNode.instanceId);
2230
- const isHidden = hiddenInstanceIds.has(runtimeNode.instanceId);
2231
- const shouldTraverseChildren = this._constraintNodesWithAffectedDescendants.has(runtimeNode.instanceId);
2232
- let propsChanged = false;
2233
- let nextProps = vnode.props;
2234
- let nextPropsMutable = null;
2235
- const ensureMutableProps = () => {
2236
- if (nextPropsMutable === null)
2237
- nextPropsMutable = { ...propsRecord };
2238
- return nextPropsMutable;
2239
- };
2240
- if (resolved) {
2241
- const write = (name) => {
2242
- const raw = resolved[name];
2243
- if (raw === undefined || !Number.isFinite(raw))
2244
- return;
2245
- const nextValue = Math.floor(raw);
2246
- if (propsRecord[name] === nextValue)
2247
- return;
2248
- ensureMutableProps()[name] = nextValue;
2249
- };
2250
- write("width");
2251
- write("height");
2252
- write("minWidth");
2253
- write("maxWidth");
2254
- write("minHeight");
2255
- write("maxHeight");
2256
- write("flexBasis");
2257
- if (typeof resolved.display === "number" && Number.isFinite(resolved.display)) {
2258
- const displayVisible = resolved.display > 0;
2259
- if (propsRecord.display !== displayVisible) {
2260
- ensureMutableProps().display = displayVisible;
2261
- }
2262
- }
2263
- }
2264
- if (isHidden) {
2265
- const mutable = ensureMutableProps();
2266
- mutable.display = false;
2267
- mutable.width = 0;
2268
- mutable.height = 0;
2269
- mutable.minWidth = 0;
2270
- mutable.maxWidth = 0;
2271
- mutable.minHeight = 0;
2272
- mutable.maxHeight = 0;
2273
- mutable.flex = 0;
2274
- mutable.flexBasis = 0;
2275
- }
2276
- const currentChildren = vnode.children;
2277
- let childrenChanged = false;
2278
- let nextChildren = currentChildren;
2279
- if (Array.isArray(currentChildren) && currentChildren.length > 0 && shouldTraverseChildren) {
2280
- let rebuiltChildren = null;
2281
- for (let i = 0; i < currentChildren.length; i++) {
2282
- const childVNode = currentChildren[i];
2283
- const runtimeChild = runtimeNode.children[i];
2284
- if (!runtimeChild || !childVNode || !affectedPathInstanceIds.has(runtimeChild.instanceId)) {
2285
- if (rebuiltChildren !== null)
2286
- rebuiltChildren[i] = childVNode;
2287
- continue;
2288
- }
2289
- const nextChild = this.applyConstraintOverridesToVNode(runtimeChild, valuesByInstanceId, hiddenInstanceIds, affectedPathInstanceIds);
2290
- if (nextChild !== childVNode) {
2291
- if (rebuiltChildren === null) {
2292
- rebuiltChildren = currentChildren.slice();
2293
- }
2294
- rebuiltChildren[i] = nextChild;
2295
- childrenChanged = true;
2296
- }
2297
- else if (rebuiltChildren !== null) {
2298
- rebuiltChildren[i] = childVNode;
2299
- }
2300
- }
2301
- if (rebuiltChildren !== null && childrenChanged) {
2302
- nextChildren = Object.freeze(rebuiltChildren);
2303
- }
2304
- }
2305
- if (shouldTraverseChildren && vnode.kind === "layer") {
2306
- const content = propsRecord.content;
2307
- const runtimeChild = runtimeNode.children[0];
2308
- if (runtimeChild &&
2309
- isVNodeLike(content) &&
2310
- affectedPathInstanceIds.has(runtimeChild.instanceId)) {
2311
- const nextContent = this.applyConstraintOverridesToVNode(runtimeChild, valuesByInstanceId, hiddenInstanceIds, affectedPathInstanceIds);
2312
- if (nextContent !== content) {
2313
- ensureMutableProps().content = nextContent;
2314
- }
2315
- }
2316
- }
2317
- else if (shouldTraverseChildren && vnode.kind === "modal") {
2318
- const modalProps = propsRecord;
2319
- let runtimeChildIndex = 0;
2320
- const content = modalProps.content;
2321
- if (isVNodeLike(content)) {
2322
- const runtimeChild = runtimeNode.children[runtimeChildIndex];
2323
- runtimeChildIndex++;
2324
- if (runtimeChild && affectedPathInstanceIds.has(runtimeChild.instanceId)) {
2325
- const nextContent = this.applyConstraintOverridesToVNode(runtimeChild, valuesByInstanceId, hiddenInstanceIds, affectedPathInstanceIds);
2326
- if (nextContent !== content) {
2327
- ensureMutableProps().content = nextContent;
2328
- }
2329
- }
2330
- }
2331
- const actionsRaw = modalProps.actions;
2332
- if (Array.isArray(actionsRaw) && actionsRaw.length > 0) {
2333
- let nextActions = null;
2334
- for (let i = 0; i < actionsRaw.length; i++) {
2335
- const action = actionsRaw[i];
2336
- if (!isVNodeLike(action)) {
2337
- if (nextActions !== null)
2338
- nextActions[i] = action;
2339
- continue;
2340
- }
2341
- const runtimeChild = runtimeNode.children[runtimeChildIndex];
2342
- runtimeChildIndex++;
2343
- if (!runtimeChild || !affectedPathInstanceIds.has(runtimeChild.instanceId)) {
2344
- if (nextActions !== null)
2345
- nextActions[i] = action;
2346
- continue;
2347
- }
2348
- const nextAction = this.applyConstraintOverridesToVNode(runtimeChild, valuesByInstanceId, hiddenInstanceIds, affectedPathInstanceIds);
2349
- if (nextAction !== action) {
2350
- if (nextActions === null)
2351
- nextActions = actionsRaw.slice();
2352
- nextActions[i] = nextAction;
2353
- }
2354
- else if (nextActions !== null) {
2355
- nextActions[i] = action;
2356
- }
2357
- }
2358
- if (nextActions !== null) {
2359
- ensureMutableProps().actions = Object.freeze(nextActions);
2360
- }
2361
- }
2362
- }
2363
- if (nextPropsMutable !== null) {
2364
- nextProps = Object.freeze(nextPropsMutable);
2365
- propsChanged = true;
2366
- }
2367
- if (!propsChanged && !childrenChanged)
2368
- return vnode;
2369
- return Object.freeze({
2370
- ...vnode,
2371
- ...(propsChanged ? { props: nextProps } : {}),
2372
- ...(childrenChanged ? { children: nextChildren } : {}),
1433
+ return applyConstraintOverridesToVNodeImpl({
1434
+ runtimeNode,
1435
+ valuesByInstanceId,
1436
+ hiddenInstanceIds,
1437
+ affectedPathInstanceIds,
1438
+ constraintNodesWithAffectedDescendants: this._constraintNodesWithAffectedDescendants,
2373
1439
  });
2374
1440
  }
2375
1441
  computeDropdownRect(props) {
@@ -3130,320 +2196,73 @@ export class WidgetRenderer {
3130
2196
  this.hadRoutingWidgets = hasRoutingWidgets;
3131
2197
  const routingToken = PERF_DETAIL_ENABLED ? perfMarkStart("routing_rebuild") : 0;
3132
2198
  const getRectForInstance = (instanceId) => this._pooledRectByInstanceId.get(instanceId) ?? ZERO_RECT;
3133
- // Rebuild complex widget metadata maps (id -> props) for routing.
3134
- this._pooledPrevTreeIds.clear();
3135
- for (const treeId of this.treeById.keys())
3136
- this._pooledPrevTreeIds.add(treeId);
3137
- this.virtualListById.clear();
3138
- this.buttonById.clear();
3139
- this.linkById.clear();
3140
- this.tableById.clear();
3141
- this.treeById.clear();
3142
- this.dropdownById.clear();
3143
- this.sliderById.clear();
3144
- this.selectById.clear();
3145
- this.checkboxById.clear();
3146
- this.radioGroupById.clear();
3147
- this.commandPaletteById.clear();
3148
- this.filePickerById.clear();
3149
- this.fileTreeExplorerById.clear();
3150
- this.splitPaneById.clear();
3151
- this.codeEditorById.clear();
3152
- this.diffViewerById.clear();
3153
- this.toolApprovalDialogById.clear();
3154
- this.logsConsoleById.clear();
3155
- // Rebuild overlay routing state using pooled collections.
3156
- this.layerRegistry.clear();
3157
- this._pooledCloseOnEscape.clear();
3158
- this._pooledCloseOnBackdrop.clear();
3159
- this._pooledOnClose.clear();
3160
- this._pooledDropdownStack.length = 0;
3161
- this._pooledOverlayShortcutOwners.length = 0;
3162
- this._pooledToastContainers.length = 0;
3163
- let overlaySeq = 0;
3164
- this._pooledRuntimeStack.length = 0;
3165
- this._pooledRuntimeStack.push(this.committedRoot);
3166
- while (this._pooledRuntimeStack.length > 0) {
3167
- const cur = this._pooledRuntimeStack.pop();
3168
- if (!cur)
3169
- continue;
3170
- if (this._hiddenConstraintInstanceIds.has(cur.instanceId))
3171
- continue;
3172
- const v = cur.vnode;
3173
- switch (v.kind) {
3174
- case "dropdown": {
3175
- const p = v.props;
3176
- this.dropdownById.set(p.id, p);
3177
- this._pooledDropdownStack.push(p.id);
3178
- const rect = this.computeDropdownRect(p) ?? ZERO_RECT;
3179
- const zIndex = overlaySeq++;
3180
- const layerId = `dropdown:${p.id}`;
3181
- const onClose = typeof p.onClose === "function" ? p.onClose : undefined;
3182
- this._pooledCloseOnEscape.set(layerId, true);
3183
- this._pooledCloseOnBackdrop.set(layerId, false);
3184
- if (onClose)
3185
- this._pooledOnClose.set(layerId, onClose);
3186
- const layerInput = {
3187
- id: layerId,
3188
- rect,
3189
- backdrop: "none",
3190
- modal: false,
3191
- closeOnEscape: true,
3192
- zIndex,
3193
- };
3194
- this.layerRegistry.register(onClose ? { ...layerInput, onClose } : layerInput);
3195
- this._pooledOverlayShortcutOwners.push(Object.freeze({ kind: "dropdown", id: p.id }));
3196
- break;
3197
- }
3198
- case "button": {
3199
- const p = v.props;
3200
- this.buttonById.set(p.id, p);
3201
- break;
3202
- }
3203
- case "link": {
3204
- const p = v.props;
3205
- if (typeof p.id === "string" && p.id.length > 0) {
3206
- this.linkById.set(p.id, p);
3207
- }
3208
- break;
3209
- }
3210
- case "virtualList": {
3211
- const p = v.props;
3212
- this.virtualListById.set(p.id, p);
3213
- break;
3214
- }
3215
- case "table": {
3216
- const p = v.props;
3217
- this.tableById.set(p.id, p);
3218
- break;
3219
- }
3220
- case "tree": {
3221
- const p = v.props;
3222
- this.treeById.set(p.id, p);
3223
- break;
3224
- }
3225
- case "commandPalette": {
3226
- const p = v.props;
3227
- this.commandPaletteById.set(p.id, p);
3228
- this._pooledOverlayShortcutOwners.push(Object.freeze({ kind: "commandPalette", id: p.id }));
3229
- break;
3230
- }
3231
- case "filePicker": {
3232
- const p = v.props;
3233
- this.filePickerById.set(p.id, p);
3234
- break;
3235
- }
3236
- case "fileTreeExplorer": {
3237
- const p = v.props;
3238
- this.fileTreeExplorerById.set(p.id, p);
3239
- break;
3240
- }
3241
- case "splitPane": {
3242
- const p = v.props;
3243
- this.splitPaneById.set(p.id, p);
3244
- break;
3245
- }
3246
- case "codeEditor": {
3247
- const p = v.props;
3248
- this.codeEditorById.set(p.id, p);
3249
- break;
3250
- }
3251
- case "diffViewer": {
3252
- const p = v.props;
3253
- this.diffViewerById.set(p.id, p);
3254
- break;
3255
- }
3256
- case "toolApprovalDialog": {
3257
- const p = v.props;
3258
- this.toolApprovalDialogById.set(p.id, p);
3259
- break;
3260
- }
3261
- case "logsConsole": {
3262
- const p = v.props;
3263
- this.logsConsoleById.set(p.id, p);
3264
- break;
3265
- }
3266
- case "toastContainer": {
3267
- const p = v.props;
3268
- const rect = getRectForInstance(cur.instanceId);
3269
- this._pooledToastContainers.push({ rect, props: p });
3270
- const zIndex = overlaySeq++;
3271
- const toastIdRaw = p.id;
3272
- const toastId = typeof toastIdRaw === "string" ? toastIdRaw : "default";
3273
- const layerId = `toast:${toastId}`;
3274
- this._pooledCloseOnEscape.set(layerId, false);
3275
- this._pooledCloseOnBackdrop.set(layerId, false);
3276
- this.layerRegistry.register({
3277
- id: layerId,
3278
- rect,
3279
- backdrop: "none",
3280
- modal: false,
3281
- closeOnEscape: false,
3282
- zIndex,
3283
- });
3284
- break;
3285
- }
3286
- case "modal": {
3287
- const p = v.props;
3288
- const id = typeof p.id === "string" ? p.id : null;
3289
- if (id) {
3290
- const rect = getRectForInstance(cur.instanceId);
3291
- const zIndex = overlaySeq++;
3292
- const canClose = p.closeOnEscape !== false;
3293
- this._pooledCloseOnEscape.set(id, canClose);
3294
- this._pooledCloseOnBackdrop.set(id, p.closeOnBackdrop !== false);
3295
- const cb = typeof p.onClose === "function" ? p.onClose : undefined;
3296
- if (cb)
3297
- this._pooledOnClose.set(id, cb);
3298
- const layerInput = {
3299
- id,
3300
- rect,
3301
- backdrop: p.backdrop === "none" || p.backdrop === "dim" || p.backdrop === "opaque"
3302
- ? p.backdrop
3303
- : "dim",
3304
- modal: true,
3305
- closeOnEscape: canClose,
3306
- zIndex,
3307
- };
3308
- this.layerRegistry.register(cb ? { ...layerInput, onClose: cb } : layerInput);
3309
- }
3310
- break;
3311
- }
3312
- case "layer": {
3313
- const p = v.props;
3314
- const id = typeof p.id === "string" ? p.id : null;
3315
- if (id) {
3316
- const rect = getRectForInstance(cur.instanceId);
3317
- const baseZ = typeof p.zIndex === "number" && Number.isFinite(p.zIndex)
3318
- ? Math.trunc(p.zIndex)
3319
- : null;
3320
- const zIndex = encodeLayerZIndex(baseZ, overlaySeq++);
3321
- const modal = p.modal === true;
3322
- const canClose = p.closeOnEscape !== false;
3323
- this._pooledCloseOnEscape.set(id, canClose);
3324
- this._pooledCloseOnBackdrop.set(id, false);
3325
- const cb = typeof p.onClose === "function" ? p.onClose : undefined;
3326
- if (cb)
3327
- this._pooledOnClose.set(id, cb);
3328
- const layerInput = {
3329
- id,
3330
- rect,
3331
- backdrop: p.backdrop === "none" || p.backdrop === "dim" || p.backdrop === "opaque"
3332
- ? p.backdrop
3333
- : "none",
3334
- modal,
3335
- closeOnEscape: canClose,
3336
- zIndex,
3337
- };
3338
- this.layerRegistry.register(cb ? { ...layerInput, onClose: cb } : layerInput);
3339
- }
3340
- break;
3341
- }
3342
- case "slider": {
3343
- this.sliderById.set(v.props.id, v.props);
3344
- break;
3345
- }
3346
- case "select": {
3347
- this.selectById.set(v.props.id, v.props);
3348
- break;
3349
- }
3350
- case "checkbox": {
3351
- this.checkboxById.set(v.props.id, v.props);
3352
- break;
3353
- }
3354
- case "radioGroup": {
3355
- this.radioGroupById.set(v.props.id, v.props);
3356
- break;
3357
- }
3358
- default:
3359
- break;
3360
- }
3361
- for (let i = cur.children.length - 1; i >= 0; i--) {
3362
- const c = cur.children[i];
3363
- if (c)
3364
- this._pooledRuntimeStack.push(c);
3365
- }
3366
- }
3367
- this.layerStack = Object.freeze(this.layerRegistry.getAll().map((l) => l.id));
3368
- this.closeOnEscapeByLayerId = this._pooledCloseOnEscape;
3369
- this.closeOnBackdropByLayerId = this._pooledCloseOnBackdrop;
3370
- this.onCloseByLayerId = this._pooledOnClose;
3371
- this.dropdownStack = this._pooledDropdownStack.slice();
3372
- this.overlayShortcutOwners = this._pooledOverlayShortcutOwners.slice();
3373
- this.toastContainers = this._pooledToastContainers.slice();
3374
- this.rebuildOverlayShortcutBindings();
3375
- // Build toast action maps using pooled collections.
3376
- this._pooledToastActionByFocusId.clear();
3377
- this._pooledToastActionLabelByFocusId.clear();
3378
- this._pooledToastFocusableActionIds.length = 0;
3379
- for (const tc of this._pooledToastContainers) {
3380
- if (!tc)
3381
- continue;
3382
- const rect = tc.rect;
3383
- if (rect.w <= 0 || rect.h <= 0)
3384
- continue;
3385
- const toasts = tc.props.toasts;
3386
- const maxVisible = tc.props.maxVisible ?? 5;
3387
- const maxByHeight = Math.floor(rect.h / TOAST_HEIGHT);
3388
- const visibleCount = Math.min(toasts.length, maxVisible, maxByHeight);
3389
- for (let i = 0; i < visibleCount; i++) {
3390
- const toast = toasts[i];
3391
- if (!toast?.action)
3392
- continue;
3393
- const fid = getToastActionFocusId(toast.id);
3394
- this._pooledToastActionByFocusId.set(fid, toast.action.onAction);
3395
- this._pooledToastActionLabelByFocusId.set(fid, toast.action.label);
3396
- this._pooledToastFocusableActionIds.push(fid);
3397
- }
3398
- }
3399
- this.toastActionByFocusId = this._pooledToastActionByFocusId;
3400
- this.toastActionLabelByFocusId = this._pooledToastActionLabelByFocusId;
3401
- this.toastFocusableActionIds = this._pooledToastFocusableActionIds.slice();
3402
- const baseFocusList = this.baseFocusList;
3403
- const baseEnabledById = this.baseEnabledById;
3404
- this.focusList = baseFocusList;
3405
- this.enabledById = baseEnabledById;
3406
- if (this._pooledToastFocusableActionIds.length > 0) {
3407
- this.focusList = Object.freeze([...baseFocusList, ...this.toastFocusableActionIds]);
3408
- const enabled = new Map(baseEnabledById);
3409
- for (const id of this.toastFocusableActionIds)
3410
- enabled.set(id, true);
3411
- this.enabledById = enabled;
3412
- }
2199
+ rebuildRoutingWidgetMapsAndOverlayState({
2200
+ committedRoot: this.committedRoot,
2201
+ hiddenConstraintInstanceIds: this._hiddenConstraintInstanceIds,
2202
+ pooledRuntimeStack: this._pooledRuntimeStack,
2203
+ pooledPrevTreeIds: this._pooledPrevTreeIds,
2204
+ getRectForInstance,
2205
+ computeDropdownRect: (props) => this.computeDropdownRect(props),
2206
+ layerRegistry: this.layerRegistry,
2207
+ pooledCloseOnEscape: this._pooledCloseOnEscape,
2208
+ pooledCloseOnBackdrop: this._pooledCloseOnBackdrop,
2209
+ pooledOnClose: this._pooledOnClose,
2210
+ pooledDropdownStack: this._pooledDropdownStack,
2211
+ pooledOverlayShortcutOwners: this._pooledOverlayShortcutOwners,
2212
+ pooledToastContainers: this._pooledToastContainers,
2213
+ virtualListById: this.virtualListById,
2214
+ buttonById: this.buttonById,
2215
+ linkById: this.linkById,
2216
+ tableById: this.tableById,
2217
+ treeById: this.treeById,
2218
+ dropdownById: this.dropdownById,
2219
+ sliderById: this.sliderById,
2220
+ selectById: this.selectById,
2221
+ checkboxById: this.checkboxById,
2222
+ radioGroupById: this.radioGroupById,
2223
+ commandPaletteById: this.commandPaletteById,
2224
+ filePickerById: this.filePickerById,
2225
+ fileTreeExplorerById: this.fileTreeExplorerById,
2226
+ splitPaneById: this.splitPaneById,
2227
+ codeEditorById: this.codeEditorById,
2228
+ diffViewerById: this.diffViewerById,
2229
+ toolApprovalDialogById: this.toolApprovalDialogById,
2230
+ logsConsoleById: this.logsConsoleById,
2231
+ });
3413
2232
  const preferredToastFocus = prevFocusedIdBeforeFinalize !== null &&
3414
2233
  parseToastActionFocusId(prevFocusedIdBeforeFinalize) !== null
3415
2234
  ? prevFocusedIdBeforeFinalize
3416
2235
  : null;
3417
- if (preferredToastFocus && this._pooledToastActionByFocusId.has(preferredToastFocus)) {
3418
- this.focusState = Object.freeze({
3419
- ...this.focusState,
3420
- focusedId: preferredToastFocus,
3421
- activeZoneId: null,
3422
- });
3423
- }
3424
- else {
3425
- const curFocus = this.focusState.focusedId;
3426
- if (curFocus !== null &&
3427
- parseToastActionFocusId(curFocus) !== null &&
3428
- !this._pooledToastActionByFocusId.has(curFocus)) {
3429
- this.focusState = Object.freeze({
3430
- ...this.focusState,
3431
- focusedId: null,
3432
- activeZoneId: null,
3433
- });
3434
- }
3435
- }
3436
- rebuildRenderCaches({
3437
- tableById: this.tableById,
3438
- logsConsoleById: this.logsConsoleById,
3439
- diffViewerById: this.diffViewerById,
3440
- codeEditorById: this.codeEditorById,
3441
- tableRenderCacheById: this.tableRenderCacheById,
3442
- logsConsoleRenderCacheById: this.logsConsoleRenderCacheById,
3443
- diffRenderCacheById: this.diffRenderCacheById,
3444
- codeEditorRenderCacheById: this.codeEditorRenderCacheById,
3445
- emptyStringArray: EMPTY_STRING_ARRAY,
2236
+ const finalizedOverlayState = finalizeRebuiltOverlayState({
2237
+ layerRegistry: this.layerRegistry,
2238
+ pooledCloseOnEscape: this._pooledCloseOnEscape,
2239
+ pooledCloseOnBackdrop: this._pooledCloseOnBackdrop,
2240
+ pooledOnClose: this._pooledOnClose,
2241
+ pooledDropdownStack: this._pooledDropdownStack,
2242
+ pooledOverlayShortcutOwners: this._pooledOverlayShortcutOwners,
2243
+ pooledToastContainers: this._pooledToastContainers,
2244
+ pooledToastActionByFocusId: this._pooledToastActionByFocusId,
2245
+ pooledToastActionLabelByFocusId: this._pooledToastActionLabelByFocusId,
2246
+ pooledToastFocusableActionIds: this._pooledToastFocusableActionIds,
2247
+ baseFocusList: this.baseFocusList,
2248
+ baseEnabledById: this.baseEnabledById,
2249
+ focusState: this.focusState,
2250
+ preferredToastFocus,
3446
2251
  });
2252
+ this.layerStack = finalizedOverlayState.layerStack;
2253
+ this.closeOnEscapeByLayerId = finalizedOverlayState.closeOnEscapeByLayerId;
2254
+ this.closeOnBackdropByLayerId = finalizedOverlayState.closeOnBackdropByLayerId;
2255
+ this.onCloseByLayerId = finalizedOverlayState.onCloseByLayerId;
2256
+ this.dropdownStack = finalizedOverlayState.dropdownStack;
2257
+ this.overlayShortcutOwners = finalizedOverlayState.overlayShortcutOwners;
2258
+ this.toastContainers = finalizedOverlayState.toastContainers;
2259
+ this.rebuildOverlayShortcutBindings();
2260
+ this.toastActionByFocusId = finalizedOverlayState.toastActionByFocusId;
2261
+ this.toastActionLabelByFocusId = finalizedOverlayState.toastActionLabelByFocusId;
2262
+ this.toastFocusableActionIds = finalizedOverlayState.toastFocusableActionIds;
2263
+ this.focusList = finalizedOverlayState.focusList;
2264
+ this.enabledById = finalizedOverlayState.enabledById;
2265
+ this.focusState = finalizedOverlayState.focusState;
3447
2266
  if (PERF_DETAIL_ENABLED)
3448
2267
  perfMarkEnd("routing_rebuild", routingToken);
3449
2268
  }
@@ -3452,184 +2271,47 @@ export class WidgetRenderer {
3452
2271
  // Rebuild only rect-dependent overlay/ toast routing state.
3453
2272
  const routingToken = PERF_DETAIL_ENABLED ? perfMarkStart("routing_rebuild") : 0;
3454
2273
  const getRectForInstance = (instanceId) => this._pooledRectByInstanceId.get(instanceId) ?? ZERO_RECT;
3455
- this.layerRegistry.clear();
3456
- this._pooledCloseOnEscape.clear();
3457
- this._pooledCloseOnBackdrop.clear();
3458
- this._pooledOnClose.clear();
3459
- this._pooledDropdownStack.length = 0;
3460
- this._pooledToastContainers.length = 0;
3461
- let overlaySeq = 0;
3462
- this._pooledRuntimeStack.length = 0;
3463
- this._pooledRuntimeStack.push(this.committedRoot);
3464
- while (this._pooledRuntimeStack.length > 0) {
3465
- const cur = this._pooledRuntimeStack.pop();
3466
- if (!cur)
3467
- continue;
3468
- if (this._hiddenConstraintInstanceIds.has(cur.instanceId))
3469
- continue;
3470
- const v = cur.vnode;
3471
- switch (v.kind) {
3472
- case "dropdown": {
3473
- const p = v.props;
3474
- this._pooledDropdownStack.push(p.id);
3475
- const rect = this.computeDropdownRect(p) ?? ZERO_RECT;
3476
- const zIndex = overlaySeq++;
3477
- const layerId = `dropdown:${p.id}`;
3478
- const onClose = typeof p.onClose === "function" ? p.onClose : undefined;
3479
- this._pooledCloseOnEscape.set(layerId, true);
3480
- this._pooledCloseOnBackdrop.set(layerId, false);
3481
- if (onClose)
3482
- this._pooledOnClose.set(layerId, onClose);
3483
- const layerInput = {
3484
- id: layerId,
3485
- rect,
3486
- backdrop: "none",
3487
- modal: false,
3488
- closeOnEscape: true,
3489
- zIndex,
3490
- };
3491
- this.layerRegistry.register(onClose ? { ...layerInput, onClose } : layerInput);
3492
- break;
3493
- }
3494
- case "toastContainer": {
3495
- const p = v.props;
3496
- const rect = getRectForInstance(cur.instanceId);
3497
- this._pooledToastContainers.push({ rect, props: p });
3498
- const zIndex = overlaySeq++;
3499
- const toastIdRaw = p.id;
3500
- const toastId = typeof toastIdRaw === "string" ? toastIdRaw : "default";
3501
- const layerId = `toast:${toastId}`;
3502
- this._pooledCloseOnEscape.set(layerId, false);
3503
- this._pooledCloseOnBackdrop.set(layerId, false);
3504
- this.layerRegistry.register({
3505
- id: layerId,
3506
- rect,
3507
- backdrop: "none",
3508
- modal: false,
3509
- closeOnEscape: false,
3510
- zIndex,
3511
- });
3512
- break;
3513
- }
3514
- case "modal": {
3515
- const p = v.props;
3516
- const id = typeof p.id === "string" ? p.id : null;
3517
- if (id) {
3518
- const rect = getRectForInstance(cur.instanceId);
3519
- const zIndex = overlaySeq++;
3520
- const canClose = p.closeOnEscape !== false;
3521
- this._pooledCloseOnEscape.set(id, canClose);
3522
- this._pooledCloseOnBackdrop.set(id, p.closeOnBackdrop !== false);
3523
- const cb = typeof p.onClose === "function" ? p.onClose : undefined;
3524
- if (cb)
3525
- this._pooledOnClose.set(id, cb);
3526
- const layerInput = {
3527
- id,
3528
- rect,
3529
- backdrop: p.backdrop === "none" || p.backdrop === "dim" || p.backdrop === "opaque"
3530
- ? p.backdrop
3531
- : "dim",
3532
- modal: true,
3533
- closeOnEscape: canClose,
3534
- zIndex,
3535
- };
3536
- this.layerRegistry.register(cb ? { ...layerInput, onClose: cb } : layerInput);
3537
- }
3538
- break;
3539
- }
3540
- case "layer": {
3541
- const p = v.props;
3542
- const id = typeof p.id === "string" ? p.id : null;
3543
- if (id) {
3544
- const rect = getRectForInstance(cur.instanceId);
3545
- const baseZ = typeof p.zIndex === "number" && Number.isFinite(p.zIndex)
3546
- ? Math.trunc(p.zIndex)
3547
- : null;
3548
- const zIndex = encodeLayerZIndex(baseZ, overlaySeq++);
3549
- const modal = p.modal === true;
3550
- const canClose = p.closeOnEscape !== false;
3551
- this._pooledCloseOnEscape.set(id, canClose);
3552
- this._pooledCloseOnBackdrop.set(id, false);
3553
- const cb = typeof p.onClose === "function" ? p.onClose : undefined;
3554
- if (cb)
3555
- this._pooledOnClose.set(id, cb);
3556
- const layerInput = {
3557
- id,
3558
- rect,
3559
- backdrop: p.backdrop === "none" || p.backdrop === "dim" || p.backdrop === "opaque"
3560
- ? p.backdrop
3561
- : "none",
3562
- modal,
3563
- closeOnEscape: canClose,
3564
- zIndex,
3565
- };
3566
- this.layerRegistry.register(cb ? { ...layerInput, onClose: cb } : layerInput);
3567
- }
3568
- break;
3569
- }
3570
- default:
3571
- break;
3572
- }
3573
- for (let i = cur.children.length - 1; i >= 0; i--) {
3574
- const c = cur.children[i];
3575
- if (c)
3576
- this._pooledRuntimeStack.push(c);
3577
- }
3578
- }
3579
- this.layerStack = Object.freeze(this.layerRegistry.getAll().map((l) => l.id));
3580
- this.closeOnEscapeByLayerId = this._pooledCloseOnEscape;
3581
- this.closeOnBackdropByLayerId = this._pooledCloseOnBackdrop;
3582
- this.onCloseByLayerId = this._pooledOnClose;
3583
- this.dropdownStack = this._pooledDropdownStack.slice();
3584
- this.toastContainers = this._pooledToastContainers.slice();
2274
+ rebuildOverlayStateForLayout({
2275
+ committedRoot: this.committedRoot,
2276
+ hiddenConstraintInstanceIds: this._hiddenConstraintInstanceIds,
2277
+ pooledRuntimeStack: this._pooledRuntimeStack,
2278
+ getRectForInstance,
2279
+ computeDropdownRect: (props) => this.computeDropdownRect(props),
2280
+ layerRegistry: this.layerRegistry,
2281
+ pooledCloseOnEscape: this._pooledCloseOnEscape,
2282
+ pooledCloseOnBackdrop: this._pooledCloseOnBackdrop,
2283
+ pooledOnClose: this._pooledOnClose,
2284
+ pooledDropdownStack: this._pooledDropdownStack,
2285
+ pooledOverlayShortcutOwners: this._pooledOverlayShortcutOwners,
2286
+ pooledToastContainers: this._pooledToastContainers,
2287
+ });
2288
+ const finalizedOverlayState = finalizeLayoutOnlyOverlayState({
2289
+ layerRegistry: this.layerRegistry,
2290
+ pooledCloseOnEscape: this._pooledCloseOnEscape,
2291
+ pooledCloseOnBackdrop: this._pooledCloseOnBackdrop,
2292
+ pooledOnClose: this._pooledOnClose,
2293
+ pooledDropdownStack: this._pooledDropdownStack,
2294
+ pooledToastContainers: this._pooledToastContainers,
2295
+ pooledToastActionByFocusId: this._pooledToastActionByFocusId,
2296
+ pooledToastActionLabelByFocusId: this._pooledToastActionLabelByFocusId,
2297
+ pooledToastFocusableActionIds: this._pooledToastFocusableActionIds,
2298
+ baseFocusList: this.baseFocusList,
2299
+ baseEnabledById: this.baseEnabledById,
2300
+ focusState: this.focusState,
2301
+ });
2302
+ this.layerStack = finalizedOverlayState.layerStack;
2303
+ this.closeOnEscapeByLayerId = finalizedOverlayState.closeOnEscapeByLayerId;
2304
+ this.closeOnBackdropByLayerId = finalizedOverlayState.closeOnBackdropByLayerId;
2305
+ this.onCloseByLayerId = finalizedOverlayState.onCloseByLayerId;
2306
+ this.dropdownStack = finalizedOverlayState.dropdownStack;
2307
+ this.toastContainers = finalizedOverlayState.toastContainers;
3585
2308
  this.rebuildOverlayShortcutBindings();
3586
- this._pooledToastActionByFocusId.clear();
3587
- this._pooledToastActionLabelByFocusId.clear();
3588
- this._pooledToastFocusableActionIds.length = 0;
3589
- for (const tc of this._pooledToastContainers) {
3590
- if (!tc)
3591
- continue;
3592
- const rect = tc.rect;
3593
- if (rect.w <= 0 || rect.h <= 0)
3594
- continue;
3595
- const toasts = tc.props.toasts;
3596
- const maxVisible = tc.props.maxVisible ?? 5;
3597
- const maxByHeight = Math.floor(rect.h / TOAST_HEIGHT);
3598
- const visibleCount = Math.min(toasts.length, maxVisible, maxByHeight);
3599
- for (let i = 0; i < visibleCount; i++) {
3600
- const toast = toasts[i];
3601
- if (!toast?.action)
3602
- continue;
3603
- const fid = getToastActionFocusId(toast.id);
3604
- this._pooledToastActionByFocusId.set(fid, toast.action.onAction);
3605
- this._pooledToastActionLabelByFocusId.set(fid, toast.action.label);
3606
- this._pooledToastFocusableActionIds.push(fid);
3607
- }
3608
- }
3609
- this.toastActionByFocusId = this._pooledToastActionByFocusId;
3610
- this.toastActionLabelByFocusId = this._pooledToastActionLabelByFocusId;
3611
- this.toastFocusableActionIds = this._pooledToastFocusableActionIds.slice();
3612
- const baseFocusList = this.baseFocusList;
3613
- const baseEnabledById = this.baseEnabledById;
3614
- this.focusList = baseFocusList;
3615
- this.enabledById = baseEnabledById;
3616
- if (this._pooledToastFocusableActionIds.length > 0) {
3617
- this.focusList = Object.freeze([...baseFocusList, ...this.toastFocusableActionIds]);
3618
- const enabled = new Map(baseEnabledById);
3619
- for (const id of this.toastFocusableActionIds)
3620
- enabled.set(id, true);
3621
- this.enabledById = enabled;
3622
- }
3623
- const curFocus = this.focusState.focusedId;
3624
- if (curFocus !== null &&
3625
- parseToastActionFocusId(curFocus) !== null &&
3626
- !this._pooledToastActionByFocusId.has(curFocus)) {
3627
- this.focusState = Object.freeze({
3628
- ...this.focusState,
3629
- focusedId: null,
3630
- activeZoneId: null,
3631
- });
3632
- }
2309
+ this.toastActionByFocusId = finalizedOverlayState.toastActionByFocusId;
2310
+ this.toastActionLabelByFocusId = finalizedOverlayState.toastActionLabelByFocusId;
2311
+ this.toastFocusableActionIds = finalizedOverlayState.toastFocusableActionIds;
2312
+ this.focusList = finalizedOverlayState.focusList;
2313
+ this.enabledById = finalizedOverlayState.enabledById;
2314
+ this.focusState = finalizedOverlayState.focusState;
3633
2315
  if (PERF_DETAIL_ENABLED)
3634
2316
  perfMarkEnd("routing_rebuild", routingToken);
3635
2317
  }
@@ -3643,118 +2325,62 @@ export class WidgetRenderer {
3643
2325
  }
3644
2326
  }
3645
2327
  if (doCommit && didRoutingRebuild) {
3646
- // Precompute flattened file trees for filePicker/fileTreeExplorer to avoid per-frame allocations.
3647
- for (const fp of this.filePickerById.values()) {
3648
- const s = this.treeStore.get(fp.id);
3649
- if (!readFileNodeFlatCache(s, fp.data, fp.expandedPaths)) {
3650
- const next = flattenTree(fp.data, fileNodeGetKey, fileNodeGetChildren, fileNodeHasChildren, fp.expandedPaths);
3651
- this.treeStore.set(fp.id, {
3652
- flatCache: makeFileNodeFlatCache(fp.data, fp.expandedPaths, next),
3653
- });
3654
- }
3655
- }
3656
- for (const fte of this.fileTreeExplorerById.values()) {
3657
- const s = this.treeStore.get(fte.id);
3658
- if (!readFileNodeFlatCache(s, fte.data, fte.expanded)) {
3659
- const next = flattenTree(fte.data, fileNodeGetKey, fileNodeGetChildren, fileNodeHasChildren, fte.expanded);
3660
- this.treeStore.set(fte.id, {
3661
- flatCache: makeFileNodeFlatCache(fte.data, fte.expanded, next),
3662
- });
3663
- }
3664
- }
3665
- // Garbage collect per-dropdown routing state for dropdowns that were removed.
3666
- for (const dropdownId of this.dropdownSelectedIndexById.keys()) {
3667
- if (!this.dropdownById.has(dropdownId))
3668
- this.dropdownSelectedIndexById.delete(dropdownId);
3669
- }
3670
- // Garbage collect local state for virtual lists that were removed.
3671
- for (const virtualListId of this.virtualListStore.keys()) {
3672
- if (!this.virtualListById.has(virtualListId))
3673
- this.virtualListStore.delete(virtualListId);
3674
- }
3675
- if (this.pressedVirtualList && !this.virtualListById.has(this.pressedVirtualList.id)) {
3676
- this.pressedVirtualList = null;
3677
- }
3678
- // Garbage collect local state for tables that were removed.
3679
- for (const tableId of this.tableStore.keys()) {
3680
- if (!this.tableById.has(tableId))
3681
- this.tableStore.delete(tableId);
3682
- }
3683
- // Garbage collect per-tree lazy-loading caches for trees that were removed.
3684
- for (const prevTreeId of this._pooledPrevTreeIds) {
3685
- if (!this.treeById.has(prevTreeId)) {
3686
- this.loadedTreeChildrenByTreeId.delete(prevTreeId);
3687
- const prefix = `${prevTreeId}\u0000`;
3688
- for (const tokenKey of this.treeLoadTokenByTreeAndKey.keys()) {
3689
- if (tokenKey.startsWith(prefix))
3690
- this.treeLoadTokenByTreeAndKey.delete(tokenKey);
3691
- }
3692
- }
3693
- }
3694
- // Garbage collect treeStore entries for tree-like widgets that were removed.
3695
- for (const treeLikeId of this.treeStore.keys()) {
3696
- if (!this.treeById.has(treeLikeId) &&
3697
- !this.filePickerById.has(treeLikeId) &&
3698
- !this.fileTreeExplorerById.has(treeLikeId)) {
3699
- this.treeStore.delete(treeLikeId);
3700
- }
3701
- }
3702
- // Clear stale FileTreeExplorer click tracking state.
3703
- if (this.pressedFileTree && !this.fileTreeExplorerById.has(this.pressedFileTree.id)) {
3704
- this.pressedFileTree = null;
3705
- }
3706
- if (this.lastFileTreeClick && !this.fileTreeExplorerById.has(this.lastFileTreeClick.id)) {
3707
- this.lastFileTreeClick = null;
3708
- }
3709
- if (this.pressedFilePicker && !this.filePickerById.has(this.pressedFilePicker.id)) {
3710
- this.pressedFilePicker = null;
3711
- }
3712
- if (this.lastFilePickerClick && !this.filePickerById.has(this.lastFilePickerClick.id)) {
3713
- this.lastFilePickerClick = null;
3714
- }
3715
- if (this.pressedTree && !this.treeById.has(this.pressedTree.id)) {
3716
- this.pressedTree = null;
3717
- }
3718
- if (this.lastTreeClick && !this.treeById.has(this.lastTreeClick.id)) {
3719
- this.lastTreeClick = null;
3720
- }
3721
- // Garbage collect command palette async state for palettes that were removed.
3722
- for (const id of this.commandPaletteItemsById.keys()) {
3723
- if (!this.commandPaletteById.has(id))
3724
- this.commandPaletteItemsById.delete(id);
3725
- }
3726
- for (const id of this.commandPaletteLoadingById.keys()) {
3727
- if (!this.commandPaletteById.has(id))
3728
- this.commandPaletteLoadingById.delete(id);
3729
- }
3730
- for (const id of this.commandPaletteFetchTokenById.keys()) {
3731
- if (!this.commandPaletteById.has(id))
3732
- this.commandPaletteFetchTokenById.delete(id);
3733
- }
3734
- for (const id of this.commandPaletteLastQueryById.keys()) {
3735
- if (!this.commandPaletteById.has(id))
3736
- this.commandPaletteLastQueryById.delete(id);
3737
- }
3738
- for (const id of this.commandPaletteLastSourcesRefById.keys()) {
3739
- if (!this.commandPaletteById.has(id))
3740
- this.commandPaletteLastSourcesRefById.delete(id);
3741
- }
3742
- for (const id of this.toolApprovalFocusedActionById.keys()) {
3743
- if (!this.toolApprovalDialogById.has(id))
3744
- this.toolApprovalFocusedActionById.delete(id);
3745
- }
3746
- for (const id of this.diffViewerFocusedHunkById.keys()) {
3747
- if (!this.diffViewerById.has(id))
3748
- this.diffViewerFocusedHunkById.delete(id);
3749
- }
3750
- for (const id of this.diffViewerExpandedHunksById.keys()) {
3751
- if (!this.diffViewerById.has(id))
3752
- this.diffViewerExpandedHunksById.delete(id);
3753
- }
3754
- for (const id of this.logsConsoleLastGTimeById.keys()) {
3755
- if (!this.logsConsoleById.has(id))
3756
- this.logsConsoleLastGTimeById.delete(id);
3757
- }
2328
+ const cleanedRoutingState = cleanupRoutingStateAfterRebuild({
2329
+ pooledPrevTreeIds: this._pooledPrevTreeIds,
2330
+ treeStore: this.treeStore,
2331
+ virtualListStore: this.virtualListStore,
2332
+ tableStore: this.tableStore,
2333
+ loadedTreeChildrenByTreeId: this.loadedTreeChildrenByTreeId,
2334
+ treeLoadTokenByTreeAndKey: this.treeLoadTokenByTreeAndKey,
2335
+ dropdownSelectedIndexById: this.dropdownSelectedIndexById,
2336
+ dropdownWindowStartById: this.dropdownWindowStartById,
2337
+ pressedVirtualList: this.pressedVirtualList,
2338
+ pressedFileTree: this.pressedFileTree,
2339
+ lastFileTreeClick: this.lastFileTreeClick,
2340
+ pressedFilePicker: this.pressedFilePicker,
2341
+ lastFilePickerClick: this.lastFilePickerClick,
2342
+ pressedTree: this.pressedTree,
2343
+ lastTreeClick: this.lastTreeClick,
2344
+ commandPaletteItemsById: this.commandPaletteItemsById,
2345
+ commandPaletteLoadingById: this.commandPaletteLoadingById,
2346
+ commandPaletteFetchTokenById: this.commandPaletteFetchTokenById,
2347
+ commandPaletteLastQueryById: this.commandPaletteLastQueryById,
2348
+ commandPaletteLastSourcesRefById: this.commandPaletteLastSourcesRefById,
2349
+ toolApprovalFocusedActionById: this.toolApprovalFocusedActionById,
2350
+ diffViewerFocusedHunkById: this.diffViewerFocusedHunkById,
2351
+ diffViewerExpandedHunksById: this.diffViewerExpandedHunksById,
2352
+ logsConsoleLastGTimeById: this.logsConsoleLastGTimeById,
2353
+ tableRenderCacheById: this.tableRenderCacheById,
2354
+ logsConsoleRenderCacheById: this.logsConsoleRenderCacheById,
2355
+ diffRenderCacheById: this.diffRenderCacheById,
2356
+ codeEditorRenderCacheById: this.codeEditorRenderCacheById,
2357
+ emptyStringArray: EMPTY_STRING_ARRAY,
2358
+ virtualListById: this.virtualListById,
2359
+ buttonById: this.buttonById,
2360
+ linkById: this.linkById,
2361
+ tableById: this.tableById,
2362
+ treeById: this.treeById,
2363
+ dropdownById: this.dropdownById,
2364
+ sliderById: this.sliderById,
2365
+ selectById: this.selectById,
2366
+ checkboxById: this.checkboxById,
2367
+ radioGroupById: this.radioGroupById,
2368
+ commandPaletteById: this.commandPaletteById,
2369
+ filePickerById: this.filePickerById,
2370
+ fileTreeExplorerById: this.fileTreeExplorerById,
2371
+ splitPaneById: this.splitPaneById,
2372
+ codeEditorById: this.codeEditorById,
2373
+ diffViewerById: this.diffViewerById,
2374
+ toolApprovalDialogById: this.toolApprovalDialogById,
2375
+ logsConsoleById: this.logsConsoleById,
2376
+ });
2377
+ this.pressedVirtualList = cleanedRoutingState.pressedVirtualList;
2378
+ this.pressedFileTree = cleanedRoutingState.pressedFileTree;
2379
+ this.lastFileTreeClick = cleanedRoutingState.lastFileTreeClick;
2380
+ this.pressedFilePicker = cleanedRoutingState.pressedFilePicker;
2381
+ this.lastFilePickerClick = cleanedRoutingState.lastFilePickerClick;
2382
+ this.pressedTree = cleanedRoutingState.pressedTree;
2383
+ this.lastTreeClick = cleanedRoutingState.lastTreeClick;
3758
2384
  }
3759
2385
  if (doCommit) {
3760
2386
  // Reset per-commit working values to committed props.value, and normalize cursor (docs/18).
@@ -3885,7 +2511,7 @@ export class WidgetRenderer {
3885
2511
  }
3886
2512
  for (const damageRect of damageRects) {
3887
2513
  this.builder.pushClip(damageRect.x, damageRect.y, damageRect.w, damageRect.h);
3888
- renderTree(this.builder, this.focusState, this.layoutTree, this._pooledRectById, viewport, theme, tick, DEFAULT_BASE_STYLE, this.committedRoot, this.animatedRectByInstanceId, this.animatedOpacityByInstanceId, cursorInfo, this.virtualListStore, this.tableStore, this.treeStore, this.loadedTreeChildrenByTreeId, this.commandPaletteItemsById, this.commandPaletteLoadingById, this.toolApprovalFocusedActionById, this.dropdownSelectedIndexById, this.diffViewerFocusedHunkById, this.diffViewerExpandedHunksById, this.tableRenderCacheById, this.logsConsoleRenderCacheById, this.diffRenderCacheById, this.codeEditorRenderCacheById, focusAnnouncement, { damageRect }, this.terminalProfile, this.pressedId);
2514
+ renderTree(this.builder, this.focusState, this.layoutTree, this._pooledRectById, viewport, theme, tick, DEFAULT_BASE_STYLE, this.committedRoot, this.animatedRectByInstanceId, this.animatedOpacityByInstanceId, cursorInfo, this.virtualListStore, this.tableStore, this.treeStore, this.loadedTreeChildrenByTreeId, this.commandPaletteItemsById, this.commandPaletteLoadingById, this.toolApprovalFocusedActionById, this.dropdownSelectedIndexById, this.dropdownWindowStartById, this.diffViewerFocusedHunkById, this.diffViewerExpandedHunksById, this.tableRenderCacheById, this.logsConsoleRenderCacheById, this.diffRenderCacheById, this.codeEditorRenderCacheById, focusAnnouncement, { damageRect }, this.terminalProfile, this.pressedId);
3889
2515
  this.builder.popClip();
3890
2516
  }
3891
2517
  runtimeCursorSummary = this.emitIncrementalCursor(cursorInfo);
@@ -3913,6 +2539,7 @@ export class WidgetRenderer {
3913
2539
  commandPaletteLoadingById: this.commandPaletteLoadingById,
3914
2540
  toolApprovalFocusedActionById: this.toolApprovalFocusedActionById,
3915
2541
  dropdownSelectedIndexById: this.dropdownSelectedIndexById,
2542
+ dropdownWindowStartById: this.dropdownWindowStartById,
3916
2543
  diffViewerFocusedHunkById: this.diffViewerFocusedHunkById,
3917
2544
  diffViewerExpandedHunksById: this.diffViewerExpandedHunksById,
3918
2545
  focusAnnouncement,