@rezi-ui/core 0.1.0-alpha.1
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.
- package/README.md +12 -0
- package/dist/abi.d.ts +72 -0
- package/dist/abi.d.ts.map +1 -0
- package/dist/abi.js +86 -0
- package/dist/abi.js.map +1 -0
- package/dist/app/__tests__/dirtyFlagPlan.test.d.ts +2 -0
- package/dist/app/__tests__/dirtyFlagPlan.test.d.ts.map +1 -0
- package/dist/app/__tests__/dirtyFlagPlan.test.js +207 -0
- package/dist/app/__tests__/dirtyFlagPlan.test.js.map +1 -0
- package/dist/app/__tests__/eventPump.test.d.ts +2 -0
- package/dist/app/__tests__/eventPump.test.d.ts.map +1 -0
- package/dist/app/__tests__/eventPump.test.js +48 -0
- package/dist/app/__tests__/eventPump.test.js.map +1 -0
- package/dist/app/__tests__/fatal.test.d.ts +2 -0
- package/dist/app/__tests__/fatal.test.d.ts.map +1 -0
- package/dist/app/__tests__/fatal.test.js +27 -0
- package/dist/app/__tests__/fatal.test.js.map +1 -0
- package/dist/app/__tests__/frameCoalescing.test.d.ts +2 -0
- package/dist/app/__tests__/frameCoalescing.test.d.ts.map +1 -0
- package/dist/app/__tests__/frameCoalescing.test.js +33 -0
- package/dist/app/__tests__/frameCoalescing.test.js.map +1 -0
- package/dist/app/__tests__/helpers.d.ts +39 -0
- package/dist/app/__tests__/helpers.d.ts.map +1 -0
- package/dist/app/__tests__/helpers.js +99 -0
- package/dist/app/__tests__/helpers.js.map +1 -0
- package/dist/app/__tests__/interactivePriority.test.d.ts +2 -0
- package/dist/app/__tests__/interactivePriority.test.d.ts.map +1 -0
- package/dist/app/__tests__/interactivePriority.test.js +61 -0
- package/dist/app/__tests__/interactivePriority.test.js.map +1 -0
- package/dist/app/__tests__/modes.test.d.ts +2 -0
- package/dist/app/__tests__/modes.test.d.ts.map +1 -0
- package/dist/app/__tests__/modes.test.js +48 -0
- package/dist/app/__tests__/modes.test.js.map +1 -0
- package/dist/app/__tests__/onEventHandlers.test.d.ts +2 -0
- package/dist/app/__tests__/onEventHandlers.test.d.ts.map +1 -0
- package/dist/app/__tests__/onEventHandlers.test.js +41 -0
- package/dist/app/__tests__/onEventHandlers.test.js.map +1 -0
- package/dist/app/__tests__/rawRender.test.d.ts +2 -0
- package/dist/app/__tests__/rawRender.test.d.ts.map +1 -0
- package/dist/app/__tests__/rawRender.test.js +102 -0
- package/dist/app/__tests__/rawRender.test.js.map +1 -0
- package/dist/app/__tests__/stateMachine.test.d.ts +2 -0
- package/dist/app/__tests__/stateMachine.test.d.ts.map +1 -0
- package/dist/app/__tests__/stateMachine.test.js +22 -0
- package/dist/app/__tests__/stateMachine.test.js.map +1 -0
- package/dist/app/__tests__/stop_during_frame_rejection.test.d.ts +2 -0
- package/dist/app/__tests__/stop_during_frame_rejection.test.d.ts.map +1 -0
- package/dist/app/__tests__/stop_during_frame_rejection.test.js +54 -0
- package/dist/app/__tests__/stop_during_frame_rejection.test.js.map +1 -0
- package/dist/app/__tests__/stubBackend.d.ts +23 -0
- package/dist/app/__tests__/stubBackend.d.ts.map +1 -0
- package/dist/app/__tests__/stubBackend.js +76 -0
- package/dist/app/__tests__/stubBackend.js.map +1 -0
- package/dist/app/__tests__/syncFrameAckFastPath.test.d.ts +2 -0
- package/dist/app/__tests__/syncFrameAckFastPath.test.d.ts.map +1 -0
- package/dist/app/__tests__/syncFrameAckFastPath.test.js +47 -0
- package/dist/app/__tests__/syncFrameAckFastPath.test.js.map +1 -0
- package/dist/app/__tests__/turnScheduler.test.d.ts +2 -0
- package/dist/app/__tests__/turnScheduler.test.d.ts.map +1 -0
- package/dist/app/__tests__/turnScheduler.test.js +20 -0
- package/dist/app/__tests__/turnScheduler.test.js.map +1 -0
- package/dist/app/__tests__/updates.test.d.ts +2 -0
- package/dist/app/__tests__/updates.test.d.ts.map +1 -0
- package/dist/app/__tests__/updates.test.js +81 -0
- package/dist/app/__tests__/updates.test.js.map +1 -0
- package/dist/app/__tests__/widgetRenderer.integration.test.d.ts +2 -0
- package/dist/app/__tests__/widgetRenderer.integration.test.d.ts.map +1 -0
- package/dist/app/__tests__/widgetRenderer.integration.test.js +305 -0
- package/dist/app/__tests__/widgetRenderer.integration.test.js.map +1 -0
- package/dist/app/createApp.d.ts +68 -0
- package/dist/app/createApp.d.ts.map +1 -0
- package/dist/app/createApp.js +908 -0
- package/dist/app/createApp.js.map +1 -0
- package/dist/app/rawRenderer.d.ts +58 -0
- package/dist/app/rawRenderer.d.ts.map +1 -0
- package/dist/app/rawRenderer.js +89 -0
- package/dist/app/rawRenderer.js.map +1 -0
- package/dist/app/stateMachine.d.ts +44 -0
- package/dist/app/stateMachine.d.ts.map +1 -0
- package/dist/app/stateMachine.js +76 -0
- package/dist/app/stateMachine.js.map +1 -0
- package/dist/app/turnScheduler.d.ts +43 -0
- package/dist/app/turnScheduler.d.ts.map +1 -0
- package/dist/app/turnScheduler.js +72 -0
- package/dist/app/turnScheduler.js.map +1 -0
- package/dist/app/updateQueue.d.ts +32 -0
- package/dist/app/updateQueue.d.ts.map +1 -0
- package/dist/app/updateQueue.js +37 -0
- package/dist/app/updateQueue.js.map +1 -0
- package/dist/app/widgetRenderer/codeEditorRouting.d.ts +8 -0
- package/dist/app/widgetRenderer/codeEditorRouting.d.ts.map +1 -0
- package/dist/app/widgetRenderer/codeEditorRouting.js +184 -0
- package/dist/app/widgetRenderer/codeEditorRouting.js.map +1 -0
- package/dist/app/widgetRenderer/commandPaletteRouting.d.ts +5 -0
- package/dist/app/widgetRenderer/commandPaletteRouting.d.ts.map +1 -0
- package/dist/app/widgetRenderer/commandPaletteRouting.js +143 -0
- package/dist/app/widgetRenderer/commandPaletteRouting.js.map +1 -0
- package/dist/app/widgetRenderer/fileNodeCache.d.ts +9 -0
- package/dist/app/widgetRenderer/fileNodeCache.d.ts.map +1 -0
- package/dist/app/widgetRenderer/fileNodeCache.js +34 -0
- package/dist/app/widgetRenderer/fileNodeCache.js.map +1 -0
- package/dist/app/widgetRenderer/filePickerRouting.d.ts +6 -0
- package/dist/app/widgetRenderer/filePickerRouting.d.ts.map +1 -0
- package/dist/app/widgetRenderer/filePickerRouting.js +145 -0
- package/dist/app/widgetRenderer/filePickerRouting.js.map +1 -0
- package/dist/app/widgetRenderer/renderCaches.d.ts +55 -0
- package/dist/app/widgetRenderer/renderCaches.d.ts.map +1 -0
- package/dist/app/widgetRenderer/renderCaches.js +202 -0
- package/dist/app/widgetRenderer/renderCaches.js.map +1 -0
- package/dist/app/widgetRenderer/submitFramePipeline.d.ts +18 -0
- package/dist/app/widgetRenderer/submitFramePipeline.d.ts.map +1 -0
- package/dist/app/widgetRenderer/submitFramePipeline.js +253 -0
- package/dist/app/widgetRenderer/submitFramePipeline.js.map +1 -0
- package/dist/app/widgetRenderer/toolApprovalRouting.d.ts +5 -0
- package/dist/app/widgetRenderer/toolApprovalRouting.d.ts.map +1 -0
- package/dist/app/widgetRenderer/toolApprovalRouting.js +56 -0
- package/dist/app/widgetRenderer/toolApprovalRouting.js.map +1 -0
- package/dist/app/widgetRenderer.d.ts +238 -0
- package/dist/app/widgetRenderer.d.ts.map +1 -0
- package/dist/app/widgetRenderer.js +1891 -0
- package/dist/app/widgetRenderer.js.map +1 -0
- package/dist/backend.d.ts +95 -0
- package/dist/backend.d.ts.map +1 -0
- package/dist/backend.js +10 -0
- package/dist/backend.js.map +1 -0
- package/dist/binary/__tests__/reader.test.d.ts +2 -0
- package/dist/binary/__tests__/reader.test.d.ts.map +1 -0
- package/dist/binary/__tests__/reader.test.js +35 -0
- package/dist/binary/__tests__/reader.test.js.map +1 -0
- package/dist/binary/__tests__/writer.test.d.ts +2 -0
- package/dist/binary/__tests__/writer.test.d.ts.map +1 -0
- package/dist/binary/__tests__/writer.test.js +36 -0
- package/dist/binary/__tests__/writer.test.js.map +1 -0
- package/dist/binary/parseError.d.ts +37 -0
- package/dist/binary/parseError.d.ts.map +1 -0
- package/dist/binary/parseError.js +33 -0
- package/dist/binary/parseError.js.map +1 -0
- package/dist/binary/reader.d.ts +52 -0
- package/dist/binary/reader.d.ts.map +1 -0
- package/dist/binary/reader.js +107 -0
- package/dist/binary/reader.js.map +1 -0
- package/dist/binary/writer.d.ts +59 -0
- package/dist/binary/writer.d.ts.map +1 -0
- package/dist/binary/writer.js +114 -0
- package/dist/binary/writer.js.map +1 -0
- package/dist/cursor/cursorState.d.ts +89 -0
- package/dist/cursor/cursorState.d.ts.map +1 -0
- package/dist/cursor/cursorState.js +82 -0
- package/dist/cursor/cursorState.js.map +1 -0
- package/dist/cursor/index.d.ts +9 -0
- package/dist/cursor/index.d.ts.map +1 -0
- package/dist/cursor/index.js +9 -0
- package/dist/cursor/index.js.map +1 -0
- package/dist/debug/__tests__/eventTrace.test.d.ts +7 -0
- package/dist/debug/__tests__/eventTrace.test.d.ts.map +1 -0
- package/dist/debug/__tests__/eventTrace.test.js +59 -0
- package/dist/debug/__tests__/eventTrace.test.js.map +1 -0
- package/dist/debug/__tests__/frameInspector.test.d.ts +8 -0
- package/dist/debug/__tests__/frameInspector.test.d.ts.map +1 -0
- package/dist/debug/__tests__/frameInspector.test.js +121 -0
- package/dist/debug/__tests__/frameInspector.test.js.map +1 -0
- package/dist/debug/__tests__/parsers.test.d.ts +8 -0
- package/dist/debug/__tests__/parsers.test.d.ts.map +1 -0
- package/dist/debug/__tests__/parsers.test.js +265 -0
- package/dist/debug/__tests__/parsers.test.js.map +1 -0
- package/dist/debug/__tests__/stateTimeline.test.d.ts +7 -0
- package/dist/debug/__tests__/stateTimeline.test.d.ts.map +1 -0
- package/dist/debug/__tests__/stateTimeline.test.js +55 -0
- package/dist/debug/__tests__/stateTimeline.test.js.map +1 -0
- package/dist/debug/__tests__/uiDebug.test.d.ts +2 -0
- package/dist/debug/__tests__/uiDebug.test.d.ts.map +1 -0
- package/dist/debug/__tests__/uiDebug.test.js +18 -0
- package/dist/debug/__tests__/uiDebug.test.js.map +1 -0
- package/dist/debug/constants.d.ts +84 -0
- package/dist/debug/constants.d.ts.map +1 -0
- package/dist/debug/constants.js +165 -0
- package/dist/debug/constants.js.map +1 -0
- package/dist/debug/debug.d.ts +14 -0
- package/dist/debug/debug.d.ts.map +1 -0
- package/dist/debug/debug.js +54 -0
- package/dist/debug/debug.js.map +1 -0
- package/dist/debug/debugController.d.ts +151 -0
- package/dist/debug/debugController.d.ts.map +1 -0
- package/dist/debug/debugController.js +232 -0
- package/dist/debug/debugController.js.map +1 -0
- package/dist/debug/errorAggregator.d.ts +89 -0
- package/dist/debug/errorAggregator.d.ts.map +1 -0
- package/dist/debug/errorAggregator.js +150 -0
- package/dist/debug/errorAggregator.js.map +1 -0
- package/dist/debug/eventTrace.d.ts +90 -0
- package/dist/debug/eventTrace.d.ts.map +1 -0
- package/dist/debug/eventTrace.js +153 -0
- package/dist/debug/eventTrace.js.map +1 -0
- package/dist/debug/frameInspector.d.ts +88 -0
- package/dist/debug/frameInspector.d.ts.map +1 -0
- package/dist/debug/frameInspector.js +140 -0
- package/dist/debug/frameInspector.js.map +1 -0
- package/dist/debug/index.d.ts +25 -0
- package/dist/debug/index.d.ts.map +1 -0
- package/dist/debug/index.js +58 -0
- package/dist/debug/index.js.map +1 -0
- package/dist/debug/parsers.d.ts +138 -0
- package/dist/debug/parsers.d.ts.map +1 -0
- package/dist/debug/parsers.js +397 -0
- package/dist/debug/parsers.js.map +1 -0
- package/dist/debug/stateTimeline.d.ts +73 -0
- package/dist/debug/stateTimeline.d.ts.map +1 -0
- package/dist/debug/stateTimeline.js +109 -0
- package/dist/debug/stateTimeline.js.map +1 -0
- package/dist/debug/types.d.ts +261 -0
- package/dist/debug/types.d.ts.map +1 -0
- package/dist/debug/types.js +13 -0
- package/dist/debug/types.js.map +1 -0
- package/dist/drawApi.d.ts +74 -0
- package/dist/drawApi.d.ts.map +1 -0
- package/dist/drawApi.js +6 -0
- package/dist/drawApi.js.map +1 -0
- package/dist/drawlist/__tests__/builder_v1_golden.test.d.ts +2 -0
- package/dist/drawlist/__tests__/builder_v1_golden.test.d.ts.map +1 -0
- package/dist/drawlist/__tests__/builder_v1_golden.test.js +132 -0
- package/dist/drawlist/__tests__/builder_v1_golden.test.js.map +1 -0
- package/dist/drawlist/__tests__/builder_v1_text_run.test.d.ts +2 -0
- package/dist/drawlist/__tests__/builder_v1_text_run.test.d.ts.map +1 -0
- package/dist/drawlist/__tests__/builder_v1_text_run.test.js +93 -0
- package/dist/drawlist/__tests__/builder_v1_text_run.test.js.map +1 -0
- package/dist/drawlist/__tests__/builder_v1_validate_caps.test.d.ts +2 -0
- package/dist/drawlist/__tests__/builder_v1_validate_caps.test.d.ts.map +1 -0
- package/dist/drawlist/__tests__/builder_v1_validate_caps.test.js +116 -0
- package/dist/drawlist/__tests__/builder_v1_validate_caps.test.js.map +1 -0
- package/dist/drawlist/__tests__/builder_v2_cursor.test.d.ts +12 -0
- package/dist/drawlist/__tests__/builder_v2_cursor.test.d.ts.map +1 -0
- package/dist/drawlist/__tests__/builder_v2_cursor.test.js +201 -0
- package/dist/drawlist/__tests__/builder_v2_cursor.test.js.map +1 -0
- package/dist/drawlist/builder_v1.d.ts +69 -0
- package/dist/drawlist/builder_v1.d.ts.map +1 -0
- package/dist/drawlist/builder_v1.js +984 -0
- package/dist/drawlist/builder_v1.js.map +1 -0
- package/dist/drawlist/builder_v2.d.ts +57 -0
- package/dist/drawlist/builder_v2.d.ts.map +1 -0
- package/dist/drawlist/builder_v2.js +953 -0
- package/dist/drawlist/builder_v2.js.map +1 -0
- package/dist/drawlist/index.d.ts +13 -0
- package/dist/drawlist/index.d.ts.map +1 -0
- package/dist/drawlist/index.js +12 -0
- package/dist/drawlist/index.js.map +1 -0
- package/dist/drawlist/types.d.ts +138 -0
- package/dist/drawlist/types.d.ts.map +1 -0
- package/dist/drawlist/types.js +14 -0
- package/dist/drawlist/types.js.map +1 -0
- package/dist/events.d.ts +70 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +7 -0
- package/dist/events.js.map +1 -0
- package/dist/focus/styles.d.ts +213 -0
- package/dist/focus/styles.d.ts.map +1 -0
- package/dist/focus/styles.js +267 -0
- package/dist/focus/styles.js.map +1 -0
- package/dist/forms/__tests__/useForm.test.d.ts +7 -0
- package/dist/forms/__tests__/useForm.test.d.ts.map +1 -0
- package/dist/forms/__tests__/useForm.test.js +371 -0
- package/dist/forms/__tests__/useForm.test.js.map +1 -0
- package/dist/forms/bind.d.ts +15 -0
- package/dist/forms/bind.d.ts.map +1 -0
- package/dist/forms/bind.js +40 -0
- package/dist/forms/bind.js.map +1 -0
- package/dist/forms/index.d.ts +10 -0
- package/dist/forms/index.d.ts.map +1 -0
- package/dist/forms/index.js +9 -0
- package/dist/forms/index.js.map +1 -0
- package/dist/forms/types.d.ts +101 -0
- package/dist/forms/types.d.ts.map +1 -0
- package/dist/forms/types.js +10 -0
- package/dist/forms/types.js.map +1 -0
- package/dist/forms/useForm.d.ts +54 -0
- package/dist/forms/useForm.d.ts.map +1 -0
- package/dist/forms/useForm.js +316 -0
- package/dist/forms/useForm.js.map +1 -0
- package/dist/forms/validation.d.ts +67 -0
- package/dist/forms/validation.d.ts.map +1 -0
- package/dist/forms/validation.js +135 -0
- package/dist/forms/validation.js.map +1 -0
- package/dist/icons/index.d.ts +5 -0
- package/dist/icons/index.d.ts.map +1 -0
- package/dist/icons/index.js +9 -0
- package/dist/icons/index.js.map +1 -0
- package/dist/icons/registry.d.ts +1452 -0
- package/dist/icons/registry.d.ts.map +1 -0
- package/dist/icons/registry.js +192 -0
- package/dist/icons/registry.js.map +1 -0
- package/dist/index.d.ts +197 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +221 -0
- package/dist/index.js.map +1 -0
- package/dist/keybindings/__tests__/chordMatcher.test.d.ts +2 -0
- package/dist/keybindings/__tests__/chordMatcher.test.d.ts.map +1 -0
- package/dist/keybindings/__tests__/chordMatcher.test.js +238 -0
- package/dist/keybindings/__tests__/chordMatcher.test.js.map +1 -0
- package/dist/keybindings/__tests__/manager.test.d.ts +2 -0
- package/dist/keybindings/__tests__/manager.test.d.ts.map +1 -0
- package/dist/keybindings/__tests__/manager.test.js +377 -0
- package/dist/keybindings/__tests__/manager.test.js.map +1 -0
- package/dist/keybindings/__tests__/parser.test.d.ts +2 -0
- package/dist/keybindings/__tests__/parser.test.d.ts.map +1 -0
- package/dist/keybindings/__tests__/parser.test.js +386 -0
- package/dist/keybindings/__tests__/parser.test.js.map +1 -0
- package/dist/keybindings/chordMatcher.d.ts +75 -0
- package/dist/keybindings/chordMatcher.d.ts.map +1 -0
- package/dist/keybindings/chordMatcher.js +224 -0
- package/dist/keybindings/chordMatcher.js.map +1 -0
- package/dist/keybindings/index.d.ts +16 -0
- package/dist/keybindings/index.d.ts.map +1 -0
- package/dist/keybindings/index.js +31 -0
- package/dist/keybindings/index.js.map +1 -0
- package/dist/keybindings/keyCodes.d.ts +84 -0
- package/dist/keybindings/keyCodes.d.ts.map +1 -0
- package/dist/keybindings/keyCodes.js +182 -0
- package/dist/keybindings/keyCodes.js.map +1 -0
- package/dist/keybindings/manager.d.ts +168 -0
- package/dist/keybindings/manager.d.ts.map +1 -0
- package/dist/keybindings/manager.js +290 -0
- package/dist/keybindings/manager.js.map +1 -0
- package/dist/keybindings/parser.d.ts +71 -0
- package/dist/keybindings/parser.d.ts.map +1 -0
- package/dist/keybindings/parser.js +252 -0
- package/dist/keybindings/parser.js.map +1 -0
- package/dist/keybindings/types.d.ts +131 -0
- package/dist/keybindings/types.d.ts.map +1 -0
- package/dist/keybindings/types.js +11 -0
- package/dist/keybindings/types.js.map +1 -0
- package/dist/layout/__tests__/constraints.golden.test.d.ts +2 -0
- package/dist/layout/__tests__/constraints.golden.test.d.ts.map +1 -0
- package/dist/layout/__tests__/constraints.golden.test.js +86 -0
- package/dist/layout/__tests__/constraints.golden.test.js.map +1 -0
- package/dist/layout/__tests__/hitTest.golden.test.d.ts +2 -0
- package/dist/layout/__tests__/hitTest.golden.test.d.ts.map +1 -0
- package/dist/layout/__tests__/hitTest.golden.test.js +74 -0
- package/dist/layout/__tests__/hitTest.golden.test.js.map +1 -0
- package/dist/layout/__tests__/layout.edgecases.test.d.ts +2 -0
- package/dist/layout/__tests__/layout.edgecases.test.d.ts.map +1 -0
- package/dist/layout/__tests__/layout.edgecases.test.js +152 -0
- package/dist/layout/__tests__/layout.edgecases.test.js.map +1 -0
- package/dist/layout/__tests__/layout.golden.test.d.ts +2 -0
- package/dist/layout/__tests__/layout.golden.test.d.ts.map +1 -0
- package/dist/layout/__tests__/layout.golden.test.js +69 -0
- package/dist/layout/__tests__/layout.golden.test.js.map +1 -0
- package/dist/layout/__tests__/layout.perf.test.d.ts +8 -0
- package/dist/layout/__tests__/layout.perf.test.d.ts.map +1 -0
- package/dist/layout/__tests__/layout.perf.test.js +179 -0
- package/dist/layout/__tests__/layout.perf.test.js.map +1 -0
- package/dist/layout/__tests__/measure.validation.test.d.ts +2 -0
- package/dist/layout/__tests__/measure.validation.test.d.ts.map +1 -0
- package/dist/layout/__tests__/measure.validation.test.js +16 -0
- package/dist/layout/__tests__/measure.validation.test.js.map +1 -0
- package/dist/layout/__tests__/spacing.test.d.ts +2 -0
- package/dist/layout/__tests__/spacing.test.d.ts.map +1 -0
- package/dist/layout/__tests__/spacing.test.js +9 -0
- package/dist/layout/__tests__/spacing.test.js.map +1 -0
- package/dist/layout/__tests__/sweep.robustness.test.d.ts +11 -0
- package/dist/layout/__tests__/sweep.robustness.test.d.ts.map +1 -0
- package/dist/layout/__tests__/sweep.robustness.test.js +491 -0
- package/dist/layout/__tests__/sweep.robustness.test.js.map +1 -0
- package/dist/layout/__tests__/textMeasure.golden.test.d.ts +2 -0
- package/dist/layout/__tests__/textMeasure.golden.test.d.ts.map +1 -0
- package/dist/layout/__tests__/textMeasure.golden.test.js +32 -0
- package/dist/layout/__tests__/textMeasure.golden.test.js.map +1 -0
- package/dist/layout/constraints.d.ts +27 -0
- package/dist/layout/constraints.d.ts.map +1 -0
- package/dist/layout/constraints.js +57 -0
- package/dist/layout/constraints.js.map +1 -0
- package/dist/layout/engine/bounds.d.ts +7 -0
- package/dist/layout/engine/bounds.d.ts.map +1 -0
- package/dist/layout/engine/bounds.js +25 -0
- package/dist/layout/engine/bounds.js.map +1 -0
- package/dist/layout/engine/flex.d.ts +11 -0
- package/dist/layout/engine/flex.d.ts.map +1 -0
- package/dist/layout/engine/flex.js +162 -0
- package/dist/layout/engine/flex.js.map +1 -0
- package/dist/layout/engine/guards.d.ts +14 -0
- package/dist/layout/engine/guards.d.ts.map +1 -0
- package/dist/layout/engine/guards.js +36 -0
- package/dist/layout/engine/guards.js.map +1 -0
- package/dist/layout/engine/layoutEngine.d.ts +41 -0
- package/dist/layout/engine/layoutEngine.d.ts.map +1 -0
- package/dist/layout/engine/layoutEngine.js +344 -0
- package/dist/layout/engine/layoutEngine.js.map +1 -0
- package/dist/layout/engine/layoutTree.d.ts +6 -0
- package/dist/layout/engine/layoutTree.d.ts.map +1 -0
- package/dist/layout/engine/layoutTree.js +16 -0
- package/dist/layout/engine/layoutTree.js.map +1 -0
- package/dist/layout/engine/pool.d.ts +10 -0
- package/dist/layout/engine/pool.d.ts.map +1 -0
- package/dist/layout/engine/pool.js +33 -0
- package/dist/layout/engine/pool.js.map +1 -0
- package/dist/layout/engine/result.d.ts +3 -0
- package/dist/layout/engine/result.d.ts.map +1 -0
- package/dist/layout/engine/result.js +4 -0
- package/dist/layout/engine/result.js.map +1 -0
- package/dist/layout/engine/types.d.ts +12 -0
- package/dist/layout/engine/types.d.ts.map +1 -0
- package/dist/layout/engine/types.js +2 -0
- package/dist/layout/engine/types.js.map +1 -0
- package/dist/layout/hitTest.d.ts +25 -0
- package/dist/layout/hitTest.d.ts.map +1 -0
- package/dist/layout/hitTest.js +111 -0
- package/dist/layout/hitTest.js.map +1 -0
- package/dist/layout/kinds/box.d.ts +10 -0
- package/dist/layout/kinds/box.d.ts.map +1 -0
- package/dist/layout/kinds/box.js +140 -0
- package/dist/layout/kinds/box.js.map +1 -0
- package/dist/layout/kinds/collections.d.ts +7 -0
- package/dist/layout/kinds/collections.d.ts.map +1 -0
- package/dist/layout/kinds/collections.js +87 -0
- package/dist/layout/kinds/collections.js.map +1 -0
- package/dist/layout/kinds/leaf.d.ts +7 -0
- package/dist/layout/kinds/leaf.d.ts.map +1 -0
- package/dist/layout/kinds/leaf.js +390 -0
- package/dist/layout/kinds/leaf.js.map +1 -0
- package/dist/layout/kinds/overlays.d.ts +10 -0
- package/dist/layout/kinds/overlays.d.ts.map +1 -0
- package/dist/layout/kinds/overlays.js +302 -0
- package/dist/layout/kinds/overlays.js.map +1 -0
- package/dist/layout/kinds/splitPane.d.ts +9 -0
- package/dist/layout/kinds/splitPane.d.ts.map +1 -0
- package/dist/layout/kinds/splitPane.js +118 -0
- package/dist/layout/kinds/splitPane.js.map +1 -0
- package/dist/layout/kinds/stack.d.ts +10 -0
- package/dist/layout/kinds/stack.d.ts.map +1 -0
- package/dist/layout/kinds/stack.js +803 -0
- package/dist/layout/kinds/stack.js.map +1 -0
- package/dist/layout/layout.d.ts +11 -0
- package/dist/layout/layout.d.ts.map +1 -0
- package/dist/layout/layout.js +10 -0
- package/dist/layout/layout.js.map +1 -0
- package/dist/layout/positioning.d.ts +124 -0
- package/dist/layout/positioning.d.ts.map +1 -0
- package/dist/layout/positioning.js +234 -0
- package/dist/layout/positioning.js.map +1 -0
- package/dist/layout/spacing-scale.d.ts +59 -0
- package/dist/layout/spacing-scale.d.ts.map +1 -0
- package/dist/layout/spacing-scale.js +79 -0
- package/dist/layout/spacing-scale.js.map +1 -0
- package/dist/layout/spacing.d.ts +46 -0
- package/dist/layout/spacing.d.ts.map +1 -0
- package/dist/layout/spacing.js +57 -0
- package/dist/layout/spacing.js.map +1 -0
- package/dist/layout/textMeasure.d.ts +72 -0
- package/dist/layout/textMeasure.d.ts.map +1 -0
- package/dist/layout/textMeasure.js +363 -0
- package/dist/layout/textMeasure.js.map +1 -0
- package/dist/layout/types.d.ts +43 -0
- package/dist/layout/types.d.ts.map +1 -0
- package/dist/layout/types.js +10 -0
- package/dist/layout/types.js.map +1 -0
- package/dist/layout/unicode/props.d.ts +23 -0
- package/dist/layout/unicode/props.d.ts.map +1 -0
- package/dist/layout/unicode/props.js +80 -0
- package/dist/layout/unicode/props.js.map +1 -0
- package/dist/layout/unicode/tables_15_1_0.d.ts +11 -0
- package/dist/layout/unicode/tables_15_1_0.d.ts.map +1 -0
- package/dist/layout/unicode/tables_15_1_0.js +416 -0
- package/dist/layout/unicode/tables_15_1_0.js.map +1 -0
- package/dist/layout/validateProps.d.ts +101 -0
- package/dist/layout/validateProps.d.ts.map +1 -0
- package/dist/layout/validateProps.js +328 -0
- package/dist/layout/validateProps.js.map +1 -0
- package/dist/perf/index.d.ts +5 -0
- package/dist/perf/index.d.ts.map +1 -0
- package/dist/perf/index.js +5 -0
- package/dist/perf/index.js.map +1 -0
- package/dist/perf/perf.d.ts +71 -0
- package/dist/perf/perf.d.ts.map +1 -0
- package/dist/perf/perf.js +239 -0
- package/dist/perf/perf.js.map +1 -0
- package/dist/protocol/__tests__/zrev_v1_fuzz_lite.test.d.ts +2 -0
- package/dist/protocol/__tests__/zrev_v1_fuzz_lite.test.d.ts.map +1 -0
- package/dist/protocol/__tests__/zrev_v1_fuzz_lite.test.js +35 -0
- package/dist/protocol/__tests__/zrev_v1_fuzz_lite.test.js.map +1 -0
- package/dist/protocol/__tests__/zrev_v1_invalid.test.d.ts +2 -0
- package/dist/protocol/__tests__/zrev_v1_invalid.test.d.ts.map +1 -0
- package/dist/protocol/__tests__/zrev_v1_invalid.test.js +128 -0
- package/dist/protocol/__tests__/zrev_v1_invalid.test.js.map +1 -0
- package/dist/protocol/__tests__/zrev_v1_valid.test.d.ts +2 -0
- package/dist/protocol/__tests__/zrev_v1_valid.test.d.ts.map +1 -0
- package/dist/protocol/__tests__/zrev_v1_valid.test.js +126 -0
- package/dist/protocol/__tests__/zrev_v1_valid.test.js.map +1 -0
- package/dist/protocol/types.d.ts +119 -0
- package/dist/protocol/types.d.ts.map +1 -0
- package/dist/protocol/types.js +14 -0
- package/dist/protocol/types.js.map +1 -0
- package/dist/protocol/zrev_v1.d.ts +52 -0
- package/dist/protocol/zrev_v1.d.ts.map +1 -0
- package/dist/protocol/zrev_v1.js +288 -0
- package/dist/protocol/zrev_v1.js.map +1 -0
- package/dist/renderer/__tests__/overlay.edge.test.d.ts +2 -0
- package/dist/renderer/__tests__/overlay.edge.test.d.ts.map +1 -0
- package/dist/renderer/__tests__/overlay.edge.test.js +101 -0
- package/dist/renderer/__tests__/overlay.edge.test.js.map +1 -0
- package/dist/renderer/__tests__/render.golden.test.d.ts +2 -0
- package/dist/renderer/__tests__/render.golden.test.d.ts.map +1 -0
- package/dist/renderer/__tests__/render.golden.test.js +220 -0
- package/dist/renderer/__tests__/render.golden.test.js.map +1 -0
- package/dist/renderer/boxGlyphs.d.ts +87 -0
- package/dist/renderer/boxGlyphs.d.ts.map +1 -0
- package/dist/renderer/boxGlyphs.js +143 -0
- package/dist/renderer/boxGlyphs.js.map +1 -0
- package/dist/renderer/renderToDrawlist/boxBorder.d.ts +42 -0
- package/dist/renderer/renderToDrawlist/boxBorder.d.ts.map +1 -0
- package/dist/renderer/renderToDrawlist/boxBorder.js +138 -0
- package/dist/renderer/renderToDrawlist/boxBorder.js.map +1 -0
- package/dist/renderer/renderToDrawlist/indices.d.ts +11 -0
- package/dist/renderer/renderToDrawlist/indices.d.ts.map +1 -0
- package/dist/renderer/renderToDrawlist/indices.js +50 -0
- package/dist/renderer/renderToDrawlist/indices.js.map +1 -0
- package/dist/renderer/renderToDrawlist/renderTree.d.ts +21 -0
- package/dist/renderer/renderToDrawlist/renderTree.d.ts.map +1 -0
- package/dist/renderer/renderToDrawlist/renderTree.js +117 -0
- package/dist/renderer/renderToDrawlist/renderTree.js.map +1 -0
- package/dist/renderer/renderToDrawlist/simpleVNode.d.ts +9 -0
- package/dist/renderer/renderToDrawlist/simpleVNode.d.ts.map +1 -0
- package/dist/renderer/renderToDrawlist/simpleVNode.js +634 -0
- package/dist/renderer/renderToDrawlist/simpleVNode.js.map +1 -0
- package/dist/renderer/renderToDrawlist/spacing.d.ts +34 -0
- package/dist/renderer/renderToDrawlist/spacing.d.ts.map +1 -0
- package/dist/renderer/renderToDrawlist/spacing.js +53 -0
- package/dist/renderer/renderToDrawlist/spacing.js.map +1 -0
- package/dist/renderer/renderToDrawlist/textStyle.d.ts +9 -0
- package/dist/renderer/renderToDrawlist/textStyle.d.ts.map +1 -0
- package/dist/renderer/renderToDrawlist/textStyle.js +58 -0
- package/dist/renderer/renderToDrawlist/textStyle.js.map +1 -0
- package/dist/renderer/renderToDrawlist/types.d.ts +96 -0
- package/dist/renderer/renderToDrawlist/types.d.ts.map +1 -0
- package/dist/renderer/renderToDrawlist/types.js +2 -0
- package/dist/renderer/renderToDrawlist/types.js.map +1 -0
- package/dist/renderer/renderToDrawlist/widgets/basic.d.ts +17 -0
- package/dist/renderer/renderToDrawlist/widgets/basic.d.ts.map +1 -0
- package/dist/renderer/renderToDrawlist/widgets/basic.js +1149 -0
- package/dist/renderer/renderToDrawlist/widgets/basic.js.map +1 -0
- package/dist/renderer/renderToDrawlist/widgets/collections.d.ts +10 -0
- package/dist/renderer/renderToDrawlist/widgets/collections.d.ts.map +1 -0
- package/dist/renderer/renderToDrawlist/widgets/collections.js +304 -0
- package/dist/renderer/renderToDrawlist/widgets/collections.js.map +1 -0
- package/dist/renderer/renderToDrawlist/widgets/containers.d.ts +10 -0
- package/dist/renderer/renderToDrawlist/widgets/containers.d.ts.map +1 -0
- package/dist/renderer/renderToDrawlist/widgets/containers.js +242 -0
- package/dist/renderer/renderToDrawlist/widgets/containers.js.map +1 -0
- package/dist/renderer/renderToDrawlist/widgets/editors.d.ts +17 -0
- package/dist/renderer/renderToDrawlist/widgets/editors.d.ts.map +1 -0
- package/dist/renderer/renderToDrawlist/widgets/editors.js +497 -0
- package/dist/renderer/renderToDrawlist/widgets/editors.js.map +1 -0
- package/dist/renderer/renderToDrawlist/widgets/files.d.ts +13 -0
- package/dist/renderer/renderToDrawlist/widgets/files.d.ts.map +1 -0
- package/dist/renderer/renderToDrawlist/widgets/files.js +288 -0
- package/dist/renderer/renderToDrawlist/widgets/files.js.map +1 -0
- package/dist/renderer/renderToDrawlist/widgets/overlays.d.ts +21 -0
- package/dist/renderer/renderToDrawlist/widgets/overlays.d.ts.map +1 -0
- package/dist/renderer/renderToDrawlist/widgets/overlays.js +358 -0
- package/dist/renderer/renderToDrawlist/widgets/overlays.js.map +1 -0
- package/dist/renderer/renderToDrawlist.d.ts +21 -0
- package/dist/renderer/renderToDrawlist.d.ts.map +1 -0
- package/dist/renderer/renderToDrawlist.js +53 -0
- package/dist/renderer/renderToDrawlist.js.map +1 -0
- package/dist/renderer/scrollbar.d.ts +129 -0
- package/dist/renderer/scrollbar.d.ts.map +1 -0
- package/dist/renderer/scrollbar.js +219 -0
- package/dist/renderer/scrollbar.js.map +1 -0
- package/dist/renderer/shadow.d.ts +74 -0
- package/dist/renderer/shadow.d.ts.map +1 -0
- package/dist/renderer/shadow.js +118 -0
- package/dist/renderer/shadow.js.map +1 -0
- package/dist/renderer/styles.d.ts +28 -0
- package/dist/renderer/styles.d.ts.map +1 -0
- package/dist/renderer/styles.js +42 -0
- package/dist/renderer/styles.js.map +1 -0
- package/dist/runtime/__tests__/duplicateIdFatal.test.d.ts +2 -0
- package/dist/runtime/__tests__/duplicateIdFatal.test.d.ts.map +1 -0
- package/dist/runtime/__tests__/duplicateIdFatal.test.js +45 -0
- package/dist/runtime/__tests__/duplicateIdFatal.test.js.map +1 -0
- package/dist/runtime/__tests__/duplicateKeyFatal.test.d.ts +2 -0
- package/dist/runtime/__tests__/duplicateKeyFatal.test.d.ts.map +1 -0
- package/dist/runtime/__tests__/duplicateKeyFatal.test.js +20 -0
- package/dist/runtime/__tests__/duplicateKeyFatal.test.js.map +1 -0
- package/dist/runtime/__tests__/focusList.golden.test.d.ts +2 -0
- package/dist/runtime/__tests__/focusList.golden.test.d.ts.map +1 -0
- package/dist/runtime/__tests__/focusList.golden.test.js +98 -0
- package/dist/runtime/__tests__/focusList.golden.test.js.map +1 -0
- package/dist/runtime/__tests__/focusZones.golden.test.d.ts +16 -0
- package/dist/runtime/__tests__/focusZones.golden.test.d.ts.map +1 -0
- package/dist/runtime/__tests__/focusZones.golden.test.js +594 -0
- package/dist/runtime/__tests__/focusZones.golden.test.js.map +1 -0
- package/dist/runtime/__tests__/inputRouting.golden.test.d.ts +2 -0
- package/dist/runtime/__tests__/inputRouting.golden.test.d.ts.map +1 -0
- package/dist/runtime/__tests__/inputRouting.golden.test.js +56 -0
- package/dist/runtime/__tests__/inputRouting.golden.test.js.map +1 -0
- package/dist/runtime/__tests__/keyRouting.golden.test.d.ts +2 -0
- package/dist/runtime/__tests__/keyRouting.golden.test.d.ts.map +1 -0
- package/dist/runtime/__tests__/keyRouting.golden.test.js +43 -0
- package/dist/runtime/__tests__/keyRouting.golden.test.js.map +1 -0
- package/dist/runtime/__tests__/localStateStore.test.d.ts +2 -0
- package/dist/runtime/__tests__/localStateStore.test.d.ts.map +1 -0
- package/dist/runtime/__tests__/localStateStore.test.js +25 -0
- package/dist/runtime/__tests__/localStateStore.test.js.map +1 -0
- package/dist/runtime/__tests__/mouseRouting.golden.test.d.ts +2 -0
- package/dist/runtime/__tests__/mouseRouting.golden.test.d.ts.map +1 -0
- package/dist/runtime/__tests__/mouseRouting.golden.test.js +47 -0
- package/dist/runtime/__tests__/mouseRouting.golden.test.js.map +1 -0
- package/dist/runtime/__tests__/reconcile.test.d.ts +2 -0
- package/dist/runtime/__tests__/reconcile.test.d.ts.map +1 -0
- package/dist/runtime/__tests__/reconcile.test.js +46 -0
- package/dist/runtime/__tests__/reconcile.test.js.map +1 -0
- package/dist/runtime/__tests__/widgetMeta.test.d.ts +2 -0
- package/dist/runtime/__tests__/widgetMeta.test.d.ts.map +1 -0
- package/dist/runtime/__tests__/widgetMeta.test.js +196 -0
- package/dist/runtime/__tests__/widgetMeta.test.js.map +1 -0
- package/dist/runtime/commit.d.ts +76 -0
- package/dist/runtime/commit.d.ts.map +1 -0
- package/dist/runtime/commit.js +366 -0
- package/dist/runtime/commit.js.map +1 -0
- package/dist/runtime/focus.d.ts +162 -0
- package/dist/runtime/focus.d.ts.map +1 -0
- package/dist/runtime/focus.js +488 -0
- package/dist/runtime/focus.js.map +1 -0
- package/dist/runtime/inputEditor.d.ts +49 -0
- package/dist/runtime/inputEditor.d.ts.map +1 -0
- package/dist/runtime/inputEditor.js +312 -0
- package/dist/runtime/inputEditor.js.map +1 -0
- package/dist/runtime/instance.d.ts +21 -0
- package/dist/runtime/instance.d.ts.map +1 -0
- package/dist/runtime/instance.js +27 -0
- package/dist/runtime/instance.js.map +1 -0
- package/dist/runtime/instances.d.ts +105 -0
- package/dist/runtime/instances.d.ts.map +1 -0
- package/dist/runtime/instances.js +248 -0
- package/dist/runtime/instances.js.map +1 -0
- package/dist/runtime/layers.d.ts +144 -0
- package/dist/runtime/layers.d.ts.map +1 -0
- package/dist/runtime/layers.js +264 -0
- package/dist/runtime/layers.js.map +1 -0
- package/dist/runtime/localState.d.ts +172 -0
- package/dist/runtime/localState.d.ts.map +1 -0
- package/dist/runtime/localState.js +182 -0
- package/dist/runtime/localState.js.map +1 -0
- package/dist/runtime/reconcile.d.ts +64 -0
- package/dist/runtime/reconcile.d.ts.map +1 -0
- package/dist/runtime/reconcile.js +223 -0
- package/dist/runtime/reconcile.js.map +1 -0
- package/dist/runtime/router/dropdown.d.ts +16 -0
- package/dist/runtime/router/dropdown.d.ts.map +1 -0
- package/dist/runtime/router/dropdown.js +108 -0
- package/dist/runtime/router/dropdown.js.map +1 -0
- package/dist/runtime/router/key.d.ts +10 -0
- package/dist/runtime/router/key.d.ts.map +1 -0
- package/dist/runtime/router/key.js +39 -0
- package/dist/runtime/router/key.js.map +1 -0
- package/dist/runtime/router/layer.d.ts +11 -0
- package/dist/runtime/router/layer.d.ts.map +1 -0
- package/dist/runtime/router/layer.js +45 -0
- package/dist/runtime/router/layer.js.map +1 -0
- package/dist/runtime/router/mouse.d.ts +9 -0
- package/dist/runtime/router/mouse.d.ts.map +1 -0
- package/dist/runtime/router/mouse.js +38 -0
- package/dist/runtime/router/mouse.js.map +1 -0
- package/dist/runtime/router/table.d.ts +15 -0
- package/dist/runtime/router/table.d.ts.map +1 -0
- package/dist/runtime/router/table.js +182 -0
- package/dist/runtime/router/table.js.map +1 -0
- package/dist/runtime/router/tree.d.ts +16 -0
- package/dist/runtime/router/tree.d.ts.map +1 -0
- package/dist/runtime/router/tree.js +211 -0
- package/dist/runtime/router/tree.js.map +1 -0
- package/dist/runtime/router/types.d.ts +194 -0
- package/dist/runtime/router/types.d.ts.map +1 -0
- package/dist/runtime/router/types.js +2 -0
- package/dist/runtime/router/types.js.map +1 -0
- package/dist/runtime/router/virtualList.d.ts +21 -0
- package/dist/runtime/router/virtualList.d.ts.map +1 -0
- package/dist/runtime/router/virtualList.js +167 -0
- package/dist/runtime/router/virtualList.js.map +1 -0
- package/dist/runtime/router/zones.d.ts +16 -0
- package/dist/runtime/router/zones.d.ts.map +1 -0
- package/dist/runtime/router/zones.js +118 -0
- package/dist/runtime/router/zones.js.map +1 -0
- package/dist/runtime/router.d.ts +18 -0
- package/dist/runtime/router.d.ts.map +1 -0
- package/dist/runtime/router.js +17 -0
- package/dist/runtime/router.js.map +1 -0
- package/dist/runtime/widgetMeta.d.ts +157 -0
- package/dist/runtime/widgetMeta.d.ts.map +1 -0
- package/dist/runtime/widgetMeta.js +618 -0
- package/dist/runtime/widgetMeta.js.map +1 -0
- package/dist/terminalCaps.d.ts +74 -0
- package/dist/terminalCaps.d.ts.map +1 -0
- package/dist/terminalCaps.js +61 -0
- package/dist/terminalCaps.js.map +1 -0
- package/dist/theme/__tests__/theme.test.d.ts +2 -0
- package/dist/theme/__tests__/theme.test.d.ts.map +1 -0
- package/dist/theme/__tests__/theme.test.js +28 -0
- package/dist/theme/__tests__/theme.test.js.map +1 -0
- package/dist/theme/defaultTheme.d.ts +9 -0
- package/dist/theme/defaultTheme.d.ts.map +1 -0
- package/dist/theme/defaultTheme.js +22 -0
- package/dist/theme/defaultTheme.js.map +1 -0
- package/dist/theme/index.d.ts +12 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +16 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/interop.d.ts +13 -0
- package/dist/theme/interop.d.ts.map +1 -0
- package/dist/theme/interop.js +66 -0
- package/dist/theme/interop.js.map +1 -0
- package/dist/theme/presets.d.ts +81 -0
- package/dist/theme/presets.d.ts.map +1 -0
- package/dist/theme/presets.js +293 -0
- package/dist/theme/presets.js.map +1 -0
- package/dist/theme/resolve.d.ts +69 -0
- package/dist/theme/resolve.d.ts.map +1 -0
- package/dist/theme/resolve.js +159 -0
- package/dist/theme/resolve.js.map +1 -0
- package/dist/theme/theme.d.ts +33 -0
- package/dist/theme/theme.d.ts.map +1 -0
- package/dist/theme/theme.js +28 -0
- package/dist/theme/theme.js.map +1 -0
- package/dist/theme/tokens.d.ts +130 -0
- package/dist/theme/tokens.d.ts.map +1 -0
- package/dist/theme/tokens.js +50 -0
- package/dist/theme/tokens.js.map +1 -0
- package/dist/widgets/__tests__/basicWidgets.render.test.d.ts +2 -0
- package/dist/widgets/__tests__/basicWidgets.render.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/basicWidgets.render.test.js +182 -0
- package/dist/widgets/__tests__/basicWidgets.render.test.js.map +1 -0
- package/dist/widgets/__tests__/basicWidgets.test.d.ts +2 -0
- package/dist/widgets/__tests__/basicWidgets.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/basicWidgets.test.js +336 -0
- package/dist/widgets/__tests__/basicWidgets.test.js.map +1 -0
- package/dist/widgets/__tests__/collections.test.d.ts +2 -0
- package/dist/widgets/__tests__/collections.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/collections.test.js +91 -0
- package/dist/widgets/__tests__/collections.test.js.map +1 -0
- package/dist/widgets/__tests__/commandPalette.test.d.ts +2 -0
- package/dist/widgets/__tests__/commandPalette.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/commandPalette.test.js +13 -0
- package/dist/widgets/__tests__/commandPalette.test.js.map +1 -0
- package/dist/widgets/__tests__/composition.test.d.ts +14 -0
- package/dist/widgets/__tests__/composition.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/composition.test.js +458 -0
- package/dist/widgets/__tests__/composition.test.js.map +1 -0
- package/dist/widgets/__tests__/conditionals.test.d.ts +2 -0
- package/dist/widgets/__tests__/conditionals.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/conditionals.test.js +49 -0
- package/dist/widgets/__tests__/conditionals.test.js.map +1 -0
- package/dist/widgets/__tests__/containers.test.d.ts +2 -0
- package/dist/widgets/__tests__/containers.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/containers.test.js +98 -0
- package/dist/widgets/__tests__/containers.test.js.map +1 -0
- package/dist/widgets/__tests__/dataVizWidgets.test.d.ts +2 -0
- package/dist/widgets/__tests__/dataVizWidgets.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/dataVizWidgets.test.js +57 -0
- package/dist/widgets/__tests__/dataVizWidgets.test.js.map +1 -0
- package/dist/widgets/__tests__/dialogs.test.d.ts +2 -0
- package/dist/widgets/__tests__/dialogs.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/dialogs.test.js +29 -0
- package/dist/widgets/__tests__/dialogs.test.js.map +1 -0
- package/dist/widgets/__tests__/editors.test.d.ts +2 -0
- package/dist/widgets/__tests__/editors.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/editors.test.js +116 -0
- package/dist/widgets/__tests__/editors.test.js.map +1 -0
- package/dist/widgets/__tests__/filesWidgets.test.d.ts +2 -0
- package/dist/widgets/__tests__/filesWidgets.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/filesWidgets.test.js +52 -0
- package/dist/widgets/__tests__/filesWidgets.test.js.map +1 -0
- package/dist/widgets/__tests__/formWidgets.test.d.ts +7 -0
- package/dist/widgets/__tests__/formWidgets.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/formWidgets.test.js +241 -0
- package/dist/widgets/__tests__/formWidgets.test.js.map +1 -0
- package/dist/widgets/__tests__/infoWidgets.test.d.ts +2 -0
- package/dist/widgets/__tests__/infoWidgets.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/infoWidgets.test.js +43 -0
- package/dist/widgets/__tests__/infoWidgets.test.js.map +1 -0
- package/dist/widgets/__tests__/layers.golden.test.d.ts +14 -0
- package/dist/widgets/__tests__/layers.golden.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/layers.golden.test.js +728 -0
- package/dist/widgets/__tests__/layers.golden.test.js.map +1 -0
- package/dist/widgets/__tests__/overlays.test.d.ts +2 -0
- package/dist/widgets/__tests__/overlays.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/overlays.test.js +99 -0
- package/dist/widgets/__tests__/overlays.test.js.map +1 -0
- package/dist/widgets/__tests__/renderer.regressions.test.d.ts +2 -0
- package/dist/widgets/__tests__/renderer.regressions.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/renderer.regressions.test.js +132 -0
- package/dist/widgets/__tests__/renderer.regressions.test.js.map +1 -0
- package/dist/widgets/__tests__/styleUtils.test.d.ts +2 -0
- package/dist/widgets/__tests__/styleUtils.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/styleUtils.test.js +22 -0
- package/dist/widgets/__tests__/styleUtils.test.js.map +1 -0
- package/dist/widgets/__tests__/styled.test.d.ts +2 -0
- package/dist/widgets/__tests__/styled.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/styled.test.js +23 -0
- package/dist/widgets/__tests__/styled.test.js.map +1 -0
- package/dist/widgets/__tests__/table.golden.test.d.ts +10 -0
- package/dist/widgets/__tests__/table.golden.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/table.golden.test.js +367 -0
- package/dist/widgets/__tests__/table.golden.test.js.map +1 -0
- package/dist/widgets/__tests__/tree.golden.test.d.ts +10 -0
- package/dist/widgets/__tests__/tree.golden.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/tree.golden.test.js +501 -0
- package/dist/widgets/__tests__/tree.golden.test.js.map +1 -0
- package/dist/widgets/__tests__/virtualList.golden.test.d.ts +10 -0
- package/dist/widgets/__tests__/virtualList.golden.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/virtualList.golden.test.js +349 -0
- package/dist/widgets/__tests__/virtualList.golden.test.js.map +1 -0
- package/dist/widgets/__tests__/widgetRenderSmoke.test.d.ts +2 -0
- package/dist/widgets/__tests__/widgetRenderSmoke.test.d.ts.map +1 -0
- package/dist/widgets/__tests__/widgetRenderSmoke.test.js +311 -0
- package/dist/widgets/__tests__/widgetRenderSmoke.test.js.map +1 -0
- package/dist/widgets/checkbox.d.ts +49 -0
- package/dist/widgets/checkbox.d.ts.map +1 -0
- package/dist/widgets/checkbox.js +66 -0
- package/dist/widgets/checkbox.js.map +1 -0
- package/dist/widgets/codeEditor.d.ts +150 -0
- package/dist/widgets/codeEditor.d.ts.map +1 -0
- package/dist/widgets/codeEditor.js +434 -0
- package/dist/widgets/codeEditor.js.map +1 -0
- package/dist/widgets/collections.d.ts +10 -0
- package/dist/widgets/collections.d.ts.map +1 -0
- package/dist/widgets/collections.js +49 -0
- package/dist/widgets/collections.js.map +1 -0
- package/dist/widgets/commandPalette.d.ts +117 -0
- package/dist/widgets/commandPalette.d.ts.map +1 -0
- package/dist/widgets/commandPalette.js +230 -0
- package/dist/widgets/commandPalette.js.map +1 -0
- package/dist/widgets/composition.d.ts +202 -0
- package/dist/widgets/composition.d.ts.map +1 -0
- package/dist/widgets/composition.js +135 -0
- package/dist/widgets/composition.js.map +1 -0
- package/dist/widgets/conditionals.d.ts +9 -0
- package/dist/widgets/conditionals.d.ts.map +1 -0
- package/dist/widgets/conditionals.js +27 -0
- package/dist/widgets/conditionals.js.map +1 -0
- package/dist/widgets/debugPanel.d.ts +96 -0
- package/dist/widgets/debugPanel.d.ts.map +1 -0
- package/dist/widgets/debugPanel.js +172 -0
- package/dist/widgets/debugPanel.js.map +1 -0
- package/dist/widgets/dialogs/alert.d.ts +7 -0
- package/dist/widgets/dialogs/alert.d.ts.map +1 -0
- package/dist/widgets/dialogs/alert.js +21 -0
- package/dist/widgets/dialogs/alert.js.map +1 -0
- package/dist/widgets/dialogs/confirm.d.ts +7 -0
- package/dist/widgets/dialogs/confirm.d.ts.map +1 -0
- package/dist/widgets/dialogs/confirm.js +27 -0
- package/dist/widgets/dialogs/confirm.js.map +1 -0
- package/dist/widgets/dialogs/index.d.ts +8 -0
- package/dist/widgets/dialogs/index.d.ts.map +1 -0
- package/dist/widgets/dialogs/index.js +7 -0
- package/dist/widgets/dialogs/index.js.map +1 -0
- package/dist/widgets/dialogs/prompt.d.ts +9 -0
- package/dist/widgets/dialogs/prompt.d.ts.map +1 -0
- package/dist/widgets/dialogs/prompt.js +40 -0
- package/dist/widgets/dialogs/prompt.js.map +1 -0
- package/dist/widgets/dialogs/types.d.ts +29 -0
- package/dist/widgets/dialogs/types.d.ts.map +1 -0
- package/dist/widgets/dialogs/types.js +5 -0
- package/dist/widgets/dialogs/types.js.map +1 -0
- package/dist/widgets/diffViewer.d.ts +101 -0
- package/dist/widgets/diffViewer.d.ts.map +1 -0
- package/dist/widgets/diffViewer.js +194 -0
- package/dist/widgets/diffViewer.js.map +1 -0
- package/dist/widgets/field.d.ts +52 -0
- package/dist/widgets/field.d.ts.map +1 -0
- package/dist/widgets/field.js +62 -0
- package/dist/widgets/field.js.map +1 -0
- package/dist/widgets/logsConsole.d.ts +101 -0
- package/dist/widgets/logsConsole.d.ts.map +1 -0
- package/dist/widgets/logsConsole.js +189 -0
- package/dist/widgets/logsConsole.js.map +1 -0
- package/dist/widgets/radioGroup.d.ts +79 -0
- package/dist/widgets/radioGroup.d.ts.map +1 -0
- package/dist/widgets/radioGroup.js +145 -0
- package/dist/widgets/radioGroup.js.map +1 -0
- package/dist/widgets/select.d.ts +61 -0
- package/dist/widgets/select.d.ts.map +1 -0
- package/dist/widgets/select.js +119 -0
- package/dist/widgets/select.js.map +1 -0
- package/dist/widgets/splitPane.d.ts +92 -0
- package/dist/widgets/splitPane.d.ts.map +1 -0
- package/dist/widgets/splitPane.js +265 -0
- package/dist/widgets/splitPane.js.map +1 -0
- package/dist/widgets/style.d.ts +34 -0
- package/dist/widgets/style.d.ts.map +1 -0
- package/dist/widgets/style.js +16 -0
- package/dist/widgets/style.js.map +1 -0
- package/dist/widgets/styleUtils.d.ts +39 -0
- package/dist/widgets/styleUtils.d.ts.map +1 -0
- package/dist/widgets/styleUtils.js +42 -0
- package/dist/widgets/styleUtils.js.map +1 -0
- package/dist/widgets/styled.d.ts +21 -0
- package/dist/widgets/styled.d.ts.map +1 -0
- package/dist/widgets/styled.js +30 -0
- package/dist/widgets/styled.js.map +1 -0
- package/dist/widgets/table.d.ts +157 -0
- package/dist/widgets/table.d.ts.map +1 -0
- package/dist/widgets/table.js +338 -0
- package/dist/widgets/table.js.map +1 -0
- package/dist/widgets/toast.d.ts +89 -0
- package/dist/widgets/toast.d.ts.map +1 -0
- package/dist/widgets/toast.js +145 -0
- package/dist/widgets/toast.js.map +1 -0
- package/dist/widgets/tree.d.ts +207 -0
- package/dist/widgets/tree.d.ts.map +1 -0
- package/dist/widgets/tree.js +393 -0
- package/dist/widgets/tree.js.map +1 -0
- package/dist/widgets/types.d.ts +1400 -0
- package/dist/widgets/types.d.ts.map +1 -0
- package/dist/widgets/types.js +20 -0
- package/dist/widgets/types.js.map +1 -0
- package/dist/widgets/ui.d.ts +734 -0
- package/dist/widgets/ui.d.ts.map +1 -0
- package/dist/widgets/ui.js +851 -0
- package/dist/widgets/ui.js.map +1 -0
- package/dist/widgets/virtualList.d.ts +93 -0
- package/dist/widgets/virtualList.d.ts.map +1 -0
- package/dist/widgets/virtualList.js +258 -0
- package/dist/widgets/virtualList.js.map +1 -0
- package/package.json +97 -0
|
@@ -0,0 +1,1891 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* packages/core/src/app/widgetRenderer.ts — Widget tree renderer with focus and event routing.
|
|
3
|
+
*
|
|
4
|
+
* Why: Handles the "view mode" rendering path where users return VNode trees
|
|
5
|
+
* from a view function. Orchestrates the full widget pipeline: tree commit,
|
|
6
|
+
* layout computation, focus management, event routing, input editing, and
|
|
7
|
+
* drawlist rendering.
|
|
8
|
+
*
|
|
9
|
+
* Responsibilities:
|
|
10
|
+
* - Commit VNode tree (reconciliation, instance ID allocation)
|
|
11
|
+
* - Compute layout for viewport
|
|
12
|
+
* - Manage focus state (traversal, pending changes)
|
|
13
|
+
* - Route engine events to widgets (keyboard/mouse -> actions)
|
|
14
|
+
* - Handle input widget editing (text/key/paste events)
|
|
15
|
+
* - Render committed tree to drawlist
|
|
16
|
+
*
|
|
17
|
+
* v2 Cursor Protocol:
|
|
18
|
+
* - When useV2Cursor is enabled, uses DrawlistBuilderV2
|
|
19
|
+
* - Emits SET_CURSOR for focused Input widgets with proper position
|
|
20
|
+
*
|
|
21
|
+
* @see docs/guide/runtime-and-layout.md
|
|
22
|
+
* @see docs/guide/lifecycle-and-updates.md
|
|
23
|
+
*/
|
|
24
|
+
import { CURSOR_DEFAULTS } from "../cursor/index.js";
|
|
25
|
+
import { createDrawlistBuilderV1, createDrawlistBuilderV2, } from "../drawlist/index.js";
|
|
26
|
+
import { ZR_KEY_DOWN, ZR_KEY_ENTER, ZR_KEY_ESCAPE, ZR_KEY_SPACE, ZR_KEY_UP, ZR_MOD_SHIFT, } from "../keybindings/keyCodes.js";
|
|
27
|
+
import { hitTestFocusable } from "../layout/hitTest.js";
|
|
28
|
+
import { layout } from "../layout/layout.js";
|
|
29
|
+
import { measureTextCells } from "../layout/textMeasure.js";
|
|
30
|
+
import { PERF_DETAIL_ENABLED, PERF_ENABLED, perfMarkEnd, perfMarkStart } from "../perf/perf.js";
|
|
31
|
+
import { renderToDrawlist } from "../renderer/renderToDrawlist.js";
|
|
32
|
+
import { commitVNodeTree } from "../runtime/commit.js";
|
|
33
|
+
import { createFocusManagerState, finalizeFocusWithPreCollectedMetadata, } from "../runtime/focus.js";
|
|
34
|
+
import { applyInputEditEvent, normalizeInputCursor } from "../runtime/inputEditor.js";
|
|
35
|
+
import { createInstanceIdAllocator } from "../runtime/instance.js";
|
|
36
|
+
import { createCompositeInstanceRegistry, runPendingEffects } from "../runtime/instances.js";
|
|
37
|
+
import { createLayerRegistry, hitTestLayers } from "../runtime/layers.js";
|
|
38
|
+
import { createTableStateStore, createTreeStateStore, createVirtualListStateStore, } from "../runtime/localState.js";
|
|
39
|
+
import { routeDropdownKey, routeKeyWithZones, routeLayerEscape, routeMouse, routeTableKey, routeTreeKey, routeVirtualListKey, routeVirtualListWheel, } from "../runtime/router.js";
|
|
40
|
+
import { createWidgetMetadataCollector, } from "../runtime/widgetMeta.js";
|
|
41
|
+
import { deleteRange, insertText } from "../widgets/codeEditor.js";
|
|
42
|
+
import { getHunkScrollPosition, navigateHunk } from "../widgets/diffViewer.js";
|
|
43
|
+
import { applyFilters } from "../widgets/logsConsole.js";
|
|
44
|
+
import { computePanelCellSizes, handleDividerDrag, sizesToPercentages, } from "../widgets/splitPane.js";
|
|
45
|
+
import { TOAST_HEIGHT, getToastActionFocusId, parseToastActionFocusId } from "../widgets/toast.js";
|
|
46
|
+
import { flattenTree } from "../widgets/tree.js";
|
|
47
|
+
import { computeVisibleRange, getTotalHeight } from "../widgets/virtualList.js";
|
|
48
|
+
import { routeCodeEditorKeyDown } from "./widgetRenderer/codeEditorRouting.js";
|
|
49
|
+
import { kickoffCommandPaletteItemFetches, routeCommandPaletteKeyDown, } from "./widgetRenderer/commandPaletteRouting.js";
|
|
50
|
+
import { fileNodeGetChildren, fileNodeGetKey, fileNodeHasChildren, makeFileNodeFlatCache, readFileNodeFlatCache, } from "./widgetRenderer/fileNodeCache.js";
|
|
51
|
+
import { routeFilePickerKeyDown, routeFileTreeExplorerKeyDown, } from "./widgetRenderer/filePickerRouting.js";
|
|
52
|
+
import { rebuildRenderCaches, } from "./widgetRenderer/renderCaches.js";
|
|
53
|
+
import { buildLayoutRectIndexes, updateLayoutStabilitySignatures, } from "./widgetRenderer/submitFramePipeline.js";
|
|
54
|
+
import { routeToolApprovalDialogKeyDown } from "./widgetRenderer/toolApprovalRouting.js";
|
|
55
|
+
const UTF8_DECODER = new TextDecoder();
|
|
56
|
+
/** Format thrown value for error message. */
|
|
57
|
+
function describeThrown(v) {
|
|
58
|
+
if (v instanceof Error)
|
|
59
|
+
return `${v.name}: ${v.message}`;
|
|
60
|
+
return String(v);
|
|
61
|
+
}
|
|
62
|
+
function isI32NonNegative(n) {
|
|
63
|
+
return Number.isInteger(n) && n >= 0 && n <= 2147483647;
|
|
64
|
+
}
|
|
65
|
+
const EMPTY_ROUTING = Object.freeze({});
|
|
66
|
+
const EMPTY_STRING_ARRAY = Object.freeze([]);
|
|
67
|
+
const ROUTE_RENDER = Object.freeze({ needsRender: true });
|
|
68
|
+
const ROUTE_NO_RENDER = Object.freeze({ needsRender: false });
|
|
69
|
+
const ZERO_RECT = Object.freeze({ x: 0, y: 0, w: 0, h: 0 });
|
|
70
|
+
/**
|
|
71
|
+
* Renderer for widget view mode.
|
|
72
|
+
*
|
|
73
|
+
* Maintains committed tree, layout, focus state, and input widget state
|
|
74
|
+
* across frames. Routes engine events to produce UI actions.
|
|
75
|
+
*
|
|
76
|
+
* @typeParam S - Application state type
|
|
77
|
+
*/
|
|
78
|
+
export class WidgetRenderer {
|
|
79
|
+
backend;
|
|
80
|
+
builder;
|
|
81
|
+
useV2Cursor;
|
|
82
|
+
cursorShape;
|
|
83
|
+
cursorBlink;
|
|
84
|
+
requestRender;
|
|
85
|
+
requestView;
|
|
86
|
+
/* --- Committed Tree State --- */
|
|
87
|
+
committedRoot = null;
|
|
88
|
+
layoutTree = null;
|
|
89
|
+
/* --- Focus/Interaction State --- */
|
|
90
|
+
focusState = createFocusManagerState();
|
|
91
|
+
focusList = Object.freeze([]);
|
|
92
|
+
baseFocusList = Object.freeze([]);
|
|
93
|
+
enabledById = new Map();
|
|
94
|
+
baseEnabledById = new Map();
|
|
95
|
+
pressableIds = new Set();
|
|
96
|
+
pressedId = null;
|
|
97
|
+
pressedVirtualList = null;
|
|
98
|
+
traps = new Map();
|
|
99
|
+
/* --- Instance ID Allocation --- */
|
|
100
|
+
allocator = createInstanceIdAllocator(1);
|
|
101
|
+
/* --- Composite Widget State --- */
|
|
102
|
+
compositeRegistry = createCompositeInstanceRegistry();
|
|
103
|
+
/* --- Input Widget State --- */
|
|
104
|
+
inputById = new Map();
|
|
105
|
+
inputCursorByInstanceId = new Map();
|
|
106
|
+
inputWorkingValueByInstanceId = new Map();
|
|
107
|
+
/* --- Complex Widget Local State --- */
|
|
108
|
+
virtualListStore = createVirtualListStateStore();
|
|
109
|
+
tableStore = createTableStateStore();
|
|
110
|
+
treeStore = createTreeStateStore();
|
|
111
|
+
/* --- Tree Lazy-Loading Cache (per tree id, per node key) --- */
|
|
112
|
+
loadedTreeChildrenByTreeId = new Map();
|
|
113
|
+
treeLoadTokenByTreeAndKey = new Map();
|
|
114
|
+
nextTreeLoadToken = 1;
|
|
115
|
+
/* --- Complex Widget Metadata (rebuilt each commit) --- */
|
|
116
|
+
virtualListById = new Map();
|
|
117
|
+
buttonById = new Map();
|
|
118
|
+
tableById = new Map();
|
|
119
|
+
treeById = new Map();
|
|
120
|
+
dropdownById = new Map();
|
|
121
|
+
selectById = new Map();
|
|
122
|
+
checkboxById = new Map();
|
|
123
|
+
radioGroupById = new Map();
|
|
124
|
+
// Advanced widgets (GitHub issue #136)
|
|
125
|
+
commandPaletteById = new Map();
|
|
126
|
+
filePickerById = new Map();
|
|
127
|
+
fileTreeExplorerById = new Map();
|
|
128
|
+
splitPaneById = new Map();
|
|
129
|
+
codeEditorById = new Map();
|
|
130
|
+
diffViewerById = new Map();
|
|
131
|
+
toolApprovalDialogById = new Map();
|
|
132
|
+
logsConsoleById = new Map();
|
|
133
|
+
/* --- Advanced Widget Runtime State --- */
|
|
134
|
+
rectById = new Map();
|
|
135
|
+
splitPaneChildRectsById = new Map();
|
|
136
|
+
toastContainers = Object.freeze([]);
|
|
137
|
+
toastActionByFocusId = new Map();
|
|
138
|
+
toastFocusableActionIds = Object.freeze([]);
|
|
139
|
+
commandPaletteItemsById = new Map();
|
|
140
|
+
commandPaletteLoadingById = new Map();
|
|
141
|
+
commandPaletteFetchTokenById = new Map();
|
|
142
|
+
commandPaletteLastQueryById = new Map();
|
|
143
|
+
commandPaletteLastSourcesRefById = new Map();
|
|
144
|
+
toolApprovalFocusedActionById = new Map();
|
|
145
|
+
diffViewerFocusedHunkById = new Map();
|
|
146
|
+
diffViewerExpandedHunksById = new Map();
|
|
147
|
+
logsConsoleLastGTimeById = new Map();
|
|
148
|
+
// Tracks whether the currently committed tree needs routing rebuild traversals.
|
|
149
|
+
hadRoutingWidgets = false;
|
|
150
|
+
/* --- Render Caches (avoid per-frame recompute) --- */
|
|
151
|
+
tableRenderCacheById = new Map();
|
|
152
|
+
logsConsoleRenderCacheById = new Map();
|
|
153
|
+
diffRenderCacheById = new Map();
|
|
154
|
+
codeEditorRenderCacheById = new Map();
|
|
155
|
+
splitPaneDrag = null;
|
|
156
|
+
/* --- Overlay Routing State (rebuilt each commit) --- */
|
|
157
|
+
layerRegistry = createLayerRegistry();
|
|
158
|
+
layerStack = Object.freeze([]);
|
|
159
|
+
closeOnEscapeByLayerId = new Map();
|
|
160
|
+
closeOnBackdropByLayerId = new Map();
|
|
161
|
+
onCloseByLayerId = new Map();
|
|
162
|
+
dropdownStack = Object.freeze([]);
|
|
163
|
+
dropdownSelectedIndexById = new Map();
|
|
164
|
+
/* --- Pooled Collections (reused per-frame to reduce GC pressure) --- */
|
|
165
|
+
_metadataCollector = createWidgetMetadataCollector();
|
|
166
|
+
_pooledRectByInstanceId = new Map();
|
|
167
|
+
_pooledLayoutSigByInstanceId = new Map();
|
|
168
|
+
_pooledNextLayoutSigByInstanceId = new Map();
|
|
169
|
+
_pooledRectById = new Map();
|
|
170
|
+
_pooledSplitPaneChildRectsById = new Map();
|
|
171
|
+
_layoutMeasureCache = new WeakMap();
|
|
172
|
+
_pooledCloseOnEscape = new Map();
|
|
173
|
+
_pooledCloseOnBackdrop = new Map();
|
|
174
|
+
_pooledOnClose = new Map();
|
|
175
|
+
_pooledToastActionByFocusId = new Map();
|
|
176
|
+
_pooledLayoutStack = [];
|
|
177
|
+
_pooledRuntimeStack = [];
|
|
178
|
+
_pooledDropdownStack = [];
|
|
179
|
+
_pooledToastContainers = [];
|
|
180
|
+
_pooledToastFocusableActionIds = [];
|
|
181
|
+
// Pooled Sets for tracking previous IDs (GC cleanup detection)
|
|
182
|
+
_pooledPrevTreeIds = new Set();
|
|
183
|
+
_pooledPrevDropdownIds = new Set();
|
|
184
|
+
_pooledPrevTreeStoreIds = new Set();
|
|
185
|
+
_pooledPrevCommandPaletteIds = new Set();
|
|
186
|
+
_pooledPrevToolApprovalDialogIds = new Set();
|
|
187
|
+
_pooledPrevDiffViewerIds = new Set();
|
|
188
|
+
_pooledPrevLogsConsoleIds = new Set();
|
|
189
|
+
constructor(opts) {
|
|
190
|
+
this.backend = opts.backend;
|
|
191
|
+
this.useV2Cursor = opts.useV2Cursor === true;
|
|
192
|
+
this.cursorShape = opts.cursorShape ?? CURSOR_DEFAULTS.input.shape;
|
|
193
|
+
this.cursorBlink = opts.cursorBlink ?? CURSOR_DEFAULTS.input.blink;
|
|
194
|
+
this.requestRender = opts.requestRender ?? (() => { });
|
|
195
|
+
this.requestView = opts.requestView ?? (() => { });
|
|
196
|
+
// Widget rendering is generated from validated layout/runtime data, so we
|
|
197
|
+
// default builder param validation off here to reduce per-command overhead.
|
|
198
|
+
const validateParams = opts.drawlistValidateParams ?? false;
|
|
199
|
+
const builderOpts = {
|
|
200
|
+
...(opts.maxDrawlistBytes === undefined ? {} : { maxDrawlistBytes: opts.maxDrawlistBytes }),
|
|
201
|
+
validateParams,
|
|
202
|
+
...(opts.drawlistReuseOutputBuffer === undefined
|
|
203
|
+
? {}
|
|
204
|
+
: { reuseOutputBuffer: opts.drawlistReuseOutputBuffer }),
|
|
205
|
+
...(opts.drawlistEncodedStringCacheCap === undefined
|
|
206
|
+
? {}
|
|
207
|
+
: { encodedStringCacheCap: opts.drawlistEncodedStringCacheCap }),
|
|
208
|
+
};
|
|
209
|
+
if (opts.builder) {
|
|
210
|
+
this.builder = opts.builder;
|
|
211
|
+
}
|
|
212
|
+
else if (this.useV2Cursor) {
|
|
213
|
+
this.builder = createDrawlistBuilderV2(builderOpts);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
this.builder = createDrawlistBuilderV1(builderOpts);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Get the currently focused widget ID.
|
|
221
|
+
*
|
|
222
|
+
* @returns Focused widget ID or null if nothing focused
|
|
223
|
+
*/
|
|
224
|
+
getFocusedId() {
|
|
225
|
+
return this.focusState.focusedId;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Determine whether a key event should bypass the keybinding system.
|
|
229
|
+
*
|
|
230
|
+
* Why: When dropdowns or modal overlays are active, widgets must be able to
|
|
231
|
+
* consume Escape to close/deny/exit without being preempted by global
|
|
232
|
+
* keybindings (e.g., "Escape => menu").
|
|
233
|
+
*/
|
|
234
|
+
shouldBypassKeybindings(event) {
|
|
235
|
+
if (event.kind !== "key" || event.action !== "down")
|
|
236
|
+
return false;
|
|
237
|
+
if (event.key !== ZR_KEY_ESCAPE)
|
|
238
|
+
return false;
|
|
239
|
+
// Dropdown stack should always receive Escape for close behavior.
|
|
240
|
+
if (this.dropdownStack.length > 0)
|
|
241
|
+
return true;
|
|
242
|
+
// Modal layers should receive Escape (even if closeOnEscape=false, the
|
|
243
|
+
// focused widget inside the modal may handle Escape, e.g. CommandPalette).
|
|
244
|
+
return this.layerRegistry.getTopmostModal() !== undefined;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Route an engine event through the widget tree.
|
|
248
|
+
*
|
|
249
|
+
* Handles focus traversal (Tab/Shift+Tab), mouse interactions,
|
|
250
|
+
* keyboard activation (Enter/Space), and input widget editing.
|
|
251
|
+
*
|
|
252
|
+
* @param event - Engine event from ZREV parsing
|
|
253
|
+
* @returns Routing outcome with render flag and optional action
|
|
254
|
+
*/
|
|
255
|
+
routeEngineEvent(event) {
|
|
256
|
+
if (!this.committedRoot || !this.layoutTree)
|
|
257
|
+
return ROUTE_NO_RENDER;
|
|
258
|
+
const enabledById = this.enabledById;
|
|
259
|
+
const prevFocusedId = this.focusState.focusedId;
|
|
260
|
+
const prevPressedId = this.pressedId;
|
|
261
|
+
const focusedId = this.focusState.focusedId;
|
|
262
|
+
const mouseTargetId = event.kind === "mouse"
|
|
263
|
+
? hitTestFocusable(this.committedRoot.vnode, this.layoutTree, event.x, event.y)
|
|
264
|
+
: null;
|
|
265
|
+
let localNeedsRender = false;
|
|
266
|
+
// Overlay routing: dropdown key navigation, layer/modal ESC close, and modal backdrop blocking.
|
|
267
|
+
if (event.kind === "key" && event.action === "down") {
|
|
268
|
+
const topDropdownId = this.dropdownStack.length > 0
|
|
269
|
+
? (this.dropdownStack[this.dropdownStack.length - 1] ?? null)
|
|
270
|
+
: null;
|
|
271
|
+
if (topDropdownId) {
|
|
272
|
+
const dropdown = this.dropdownById.get(topDropdownId);
|
|
273
|
+
if (dropdown) {
|
|
274
|
+
const selectedIndex = this.dropdownSelectedIndexById.get(topDropdownId) ?? 0;
|
|
275
|
+
const ctx = {
|
|
276
|
+
dropdownId: topDropdownId,
|
|
277
|
+
items: dropdown.items,
|
|
278
|
+
selectedIndex,
|
|
279
|
+
...(dropdown.onSelect ? { onSelect: dropdown.onSelect } : {}),
|
|
280
|
+
...(dropdown.onClose ? { onClose: dropdown.onClose } : {}),
|
|
281
|
+
};
|
|
282
|
+
const r = routeDropdownKey(event, ctx);
|
|
283
|
+
if (r.nextSelectedIndex !== undefined) {
|
|
284
|
+
this.dropdownSelectedIndexById.set(topDropdownId, r.nextSelectedIndex);
|
|
285
|
+
}
|
|
286
|
+
if (r.consumed)
|
|
287
|
+
return ROUTE_RENDER;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
const layerRes = routeLayerEscape(event, {
|
|
291
|
+
layerStack: this.layerStack,
|
|
292
|
+
closeOnEscape: this.closeOnEscapeByLayerId,
|
|
293
|
+
onClose: this.onCloseByLayerId,
|
|
294
|
+
});
|
|
295
|
+
if (layerRes.consumed)
|
|
296
|
+
return ROUTE_RENDER;
|
|
297
|
+
}
|
|
298
|
+
if (event.kind === "mouse") {
|
|
299
|
+
const hit = hitTestLayers(this.layerRegistry, event.x, event.y);
|
|
300
|
+
if (hit.blocked) {
|
|
301
|
+
const blocking = hit.blockingLayer;
|
|
302
|
+
// Mouse kind 3 = down (locked by ABI).
|
|
303
|
+
if (blocking &&
|
|
304
|
+
event.mouseKind === 3 &&
|
|
305
|
+
(this.closeOnBackdropByLayerId.get(blocking.id) ?? false) === true) {
|
|
306
|
+
const cb = this.onCloseByLayerId.get(blocking.id);
|
|
307
|
+
if (cb) {
|
|
308
|
+
try {
|
|
309
|
+
cb();
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
// Swallow close callback errors to preserve routing determinism.
|
|
313
|
+
}
|
|
314
|
+
return ROUTE_RENDER;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
// Block all input to lower layers.
|
|
318
|
+
return ROUTE_NO_RENDER;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
// SplitPane divider dragging (GitHub issue #136). SplitPane is intentionally not focusable;
|
|
322
|
+
// divider drags are handled directly from mouse events.
|
|
323
|
+
if (event.kind === "mouse") {
|
|
324
|
+
const MOUSE_KIND_DOWN = 3;
|
|
325
|
+
const MOUSE_KIND_UP = 4;
|
|
326
|
+
const MOUSE_KIND_WHEEL = 5;
|
|
327
|
+
if (this.splitPaneDrag) {
|
|
328
|
+
if (event.mouseKind === MOUSE_KIND_UP) {
|
|
329
|
+
this.splitPaneDrag = null;
|
|
330
|
+
return ROUTE_RENDER;
|
|
331
|
+
}
|
|
332
|
+
if (event.mouseKind !== MOUSE_KIND_WHEEL) {
|
|
333
|
+
const drag = this.splitPaneDrag;
|
|
334
|
+
const pane = this.splitPaneById.get(drag.id);
|
|
335
|
+
if (pane) {
|
|
336
|
+
const delta = drag.direction === "horizontal" ? event.x - drag.startX : event.y - drag.startY;
|
|
337
|
+
const nextCellSizes = handleDividerDrag(drag.startCellSizes, drag.dividerIndex, delta, drag.minSizes, drag.maxSizes);
|
|
338
|
+
const nextSizes = drag.sizeMode === "percent" ? sizesToPercentages(nextCellSizes) : nextCellSizes;
|
|
339
|
+
pane.onResize(Object.freeze(nextSizes.slice()));
|
|
340
|
+
return ROUTE_RENDER;
|
|
341
|
+
}
|
|
342
|
+
// SplitPane removed mid-drag.
|
|
343
|
+
this.splitPaneDrag = null;
|
|
344
|
+
return ROUTE_RENDER;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
else if (event.mouseKind === MOUSE_KIND_DOWN) {
|
|
348
|
+
// Detect divider under cursor.
|
|
349
|
+
for (const [id, pane] of this.splitPaneById) {
|
|
350
|
+
const rect = this.rectById.get(id);
|
|
351
|
+
if (!rect || rect.w <= 0 || rect.h <= 0)
|
|
352
|
+
continue;
|
|
353
|
+
if (event.x < rect.x ||
|
|
354
|
+
event.x >= rect.x + rect.w ||
|
|
355
|
+
event.y < rect.y ||
|
|
356
|
+
event.y >= rect.y + rect.h) {
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
const childRects = this.splitPaneChildRectsById.get(id) ?? Object.freeze([]);
|
|
360
|
+
if (childRects.length < 2)
|
|
361
|
+
continue;
|
|
362
|
+
const dividerSize = Math.max(1, pane.dividerSize ?? 1);
|
|
363
|
+
const direction = pane.direction;
|
|
364
|
+
const sizeMode = pane.sizeMode ?? "percent";
|
|
365
|
+
const minSizes = pane.minSizes;
|
|
366
|
+
const maxSizes = pane.maxSizes;
|
|
367
|
+
// Hit expansion for easier grabbing: dividerSize + 2 (one cell on each side).
|
|
368
|
+
const expand = 1;
|
|
369
|
+
for (let i = 0; i < childRects.length - 1; i++) {
|
|
370
|
+
const a = childRects[i];
|
|
371
|
+
if (!a)
|
|
372
|
+
continue;
|
|
373
|
+
if (direction === "horizontal") {
|
|
374
|
+
const x0 = a.x + a.w;
|
|
375
|
+
const hitX0 = x0 - expand;
|
|
376
|
+
const hitX1 = x0 + dividerSize + expand;
|
|
377
|
+
if (event.x >= hitX0 && event.x < hitX1) {
|
|
378
|
+
const availableCells = rect.w;
|
|
379
|
+
const startCellSizes = computePanelCellSizes(childRects.length, pane.sizes, availableCells, sizeMode, dividerSize, minSizes, maxSizes).sizes;
|
|
380
|
+
this.splitPaneDrag = Object.freeze({
|
|
381
|
+
id,
|
|
382
|
+
dividerIndex: i,
|
|
383
|
+
direction,
|
|
384
|
+
sizeMode,
|
|
385
|
+
dividerSize,
|
|
386
|
+
minSizes,
|
|
387
|
+
maxSizes,
|
|
388
|
+
startX: event.x,
|
|
389
|
+
startY: event.y,
|
|
390
|
+
startCellSizes,
|
|
391
|
+
availableCells,
|
|
392
|
+
});
|
|
393
|
+
return ROUTE_RENDER;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
const y0 = a.y + a.h;
|
|
398
|
+
const hitY0 = y0 - expand;
|
|
399
|
+
const hitY1 = y0 + dividerSize + expand;
|
|
400
|
+
if (event.y >= hitY0 && event.y < hitY1) {
|
|
401
|
+
const availableCells = rect.h;
|
|
402
|
+
const startCellSizes = computePanelCellSizes(childRects.length, pane.sizes, availableCells, sizeMode, dividerSize, minSizes, maxSizes).sizes;
|
|
403
|
+
this.splitPaneDrag = Object.freeze({
|
|
404
|
+
id,
|
|
405
|
+
dividerIndex: i,
|
|
406
|
+
direction,
|
|
407
|
+
sizeMode,
|
|
408
|
+
dividerSize,
|
|
409
|
+
minSizes,
|
|
410
|
+
maxSizes,
|
|
411
|
+
startX: event.x,
|
|
412
|
+
startY: event.y,
|
|
413
|
+
startCellSizes,
|
|
414
|
+
availableCells,
|
|
415
|
+
});
|
|
416
|
+
return ROUTE_RENDER;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
// Toast interactions (GitHub issue #136): click toast to dismiss, click action to run.
|
|
424
|
+
if (event.kind === "mouse" && event.mouseKind === 3 && this.toastContainers.length > 0) {
|
|
425
|
+
for (let i = this.toastContainers.length - 1; i >= 0; i--) {
|
|
426
|
+
const tc = this.toastContainers[i];
|
|
427
|
+
if (!tc)
|
|
428
|
+
continue;
|
|
429
|
+
const rect = tc.rect;
|
|
430
|
+
if (rect.w <= 0 || rect.h <= 0)
|
|
431
|
+
continue;
|
|
432
|
+
if (event.x < rect.x ||
|
|
433
|
+
event.x >= rect.x + rect.w ||
|
|
434
|
+
event.y < rect.y ||
|
|
435
|
+
event.y >= rect.y + rect.h) {
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
438
|
+
const toasts = tc.props.toasts;
|
|
439
|
+
const maxVisible = tc.props.maxVisible ?? 5;
|
|
440
|
+
const position = tc.props.position ?? "bottom-right";
|
|
441
|
+
const maxByHeight = Math.floor(rect.h / TOAST_HEIGHT);
|
|
442
|
+
const visibleCount = Math.min(toasts.length, maxVisible, maxByHeight);
|
|
443
|
+
for (let t = 0; t < visibleCount; t++) {
|
|
444
|
+
const toast = toasts[t];
|
|
445
|
+
if (!toast)
|
|
446
|
+
continue;
|
|
447
|
+
const toastY = position.startsWith("top")
|
|
448
|
+
? rect.y + t * TOAST_HEIGHT
|
|
449
|
+
: rect.y + rect.h - (t + 1) * TOAST_HEIGHT;
|
|
450
|
+
if (event.y < toastY || event.y >= toastY + TOAST_HEIGHT)
|
|
451
|
+
continue;
|
|
452
|
+
if (toast.action && event.y === toastY + 1 && rect.w >= 10) {
|
|
453
|
+
const label = `[${toast.action.label}]`;
|
|
454
|
+
const lw = measureTextCells(label);
|
|
455
|
+
const ax = rect.x + rect.w - 2 - lw;
|
|
456
|
+
if (ax > rect.x + 4 && event.x >= ax && event.x < ax + lw) {
|
|
457
|
+
this.focusState = Object.freeze({
|
|
458
|
+
...this.focusState,
|
|
459
|
+
focusedId: getToastActionFocusId(toast.id),
|
|
460
|
+
activeZoneId: null,
|
|
461
|
+
});
|
|
462
|
+
toast.action.onAction();
|
|
463
|
+
return ROUTE_RENDER;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
tc.props.onDismiss(toast.id);
|
|
467
|
+
return ROUTE_RENDER;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
// Route complex widgets first (so arrow keys act "within" the widget, not as focus movement).
|
|
472
|
+
if (event.kind === "key" && event.action === "down" && focusedId !== null) {
|
|
473
|
+
// Toast action routing (keyboard). ToastContainer itself is not focusable; individual
|
|
474
|
+
// toast actions become focusable via runtime-local synthetic ids (PLAN.md).
|
|
475
|
+
if (parseToastActionFocusId(focusedId) !== null &&
|
|
476
|
+
(event.key === ZR_KEY_ENTER || event.key === ZR_KEY_SPACE)) {
|
|
477
|
+
const cb = this.toastActionByFocusId.get(focusedId);
|
|
478
|
+
if (cb) {
|
|
479
|
+
cb();
|
|
480
|
+
return ROUTE_RENDER;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
// Command palette routing (GitHub issue #136)
|
|
484
|
+
const palette = this.commandPaletteById.get(focusedId);
|
|
485
|
+
if (palette?.open === true) {
|
|
486
|
+
const items = this.commandPaletteItemsById.get(palette.id) ?? Object.freeze([]);
|
|
487
|
+
if (routeCommandPaletteKeyDown(event, palette, items)) {
|
|
488
|
+
return ROUTE_RENDER;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
// Tool approval dialog routing (GitHub issue #136)
|
|
492
|
+
const toolDialog = this.toolApprovalDialogById.get(focusedId);
|
|
493
|
+
if (toolDialog?.open === true) {
|
|
494
|
+
if (routeToolApprovalDialogKeyDown(event, toolDialog, this.toolApprovalFocusedActionById)) {
|
|
495
|
+
return ROUTE_RENDER;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
// File tree explorer routing (GitHub issue #136)
|
|
499
|
+
const fte = this.fileTreeExplorerById.get(focusedId);
|
|
500
|
+
if (fte) {
|
|
501
|
+
if (routeFileTreeExplorerKeyDown(event, fte, this.treeStore)) {
|
|
502
|
+
return ROUTE_RENDER;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
// File picker routing (GitHub issue #136)
|
|
506
|
+
const fp = this.filePickerById.get(focusedId);
|
|
507
|
+
if (fp) {
|
|
508
|
+
if (routeFilePickerKeyDown(event, fp, this.treeStore)) {
|
|
509
|
+
return ROUTE_RENDER;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
// Code editor routing (GitHub issue #136)
|
|
513
|
+
const editor = this.codeEditorById.get(focusedId);
|
|
514
|
+
if (editor) {
|
|
515
|
+
const rect = this.rectById.get(editor.id) ?? null;
|
|
516
|
+
const r = routeCodeEditorKeyDown(event, editor, rect);
|
|
517
|
+
if (r)
|
|
518
|
+
return r;
|
|
519
|
+
}
|
|
520
|
+
// Logs console routing (GitHub issue #136)
|
|
521
|
+
const logs = this.logsConsoleById.get(focusedId);
|
|
522
|
+
if (logs) {
|
|
523
|
+
const rect = this.rectById.get(logs.id) ?? null;
|
|
524
|
+
const viewportHeight = rect ? Math.max(1, rect.h) : 1;
|
|
525
|
+
const cached = this.logsConsoleRenderCacheById.get(logs.id);
|
|
526
|
+
const filtered = cached?.filtered ??
|
|
527
|
+
applyFilters(logs.entries, logs.levelFilter, logs.sourceFilter, logs.searchQuery);
|
|
528
|
+
const filteredLen = filtered.length;
|
|
529
|
+
const maxScroll = Math.max(0, filteredLen - viewportHeight);
|
|
530
|
+
const isShift = (event.mods & ZR_MOD_SHIFT) !== 0;
|
|
531
|
+
const key = event.key;
|
|
532
|
+
const isDown = key === ZR_KEY_DOWN || (!isShift && key === 74) /* J */;
|
|
533
|
+
const isUp = key === ZR_KEY_UP || (!isShift && key === 75) /* K */;
|
|
534
|
+
if (isDown || isUp) {
|
|
535
|
+
const delta = isUp ? -1 : 1;
|
|
536
|
+
const nextScrollTop = Math.max(0, Math.min(maxScroll, logs.scrollTop + delta));
|
|
537
|
+
if (nextScrollTop !== logs.scrollTop) {
|
|
538
|
+
logs.onScroll(nextScrollTop);
|
|
539
|
+
return ROUTE_RENDER;
|
|
540
|
+
}
|
|
541
|
+
return ROUTE_NO_RENDER;
|
|
542
|
+
}
|
|
543
|
+
if (key === 71 /* G */) {
|
|
544
|
+
if (isShift) {
|
|
545
|
+
if (logs.scrollTop !== maxScroll) {
|
|
546
|
+
logs.onScroll(maxScroll);
|
|
547
|
+
return ROUTE_RENDER;
|
|
548
|
+
}
|
|
549
|
+
return ROUTE_NO_RENDER;
|
|
550
|
+
}
|
|
551
|
+
const prevG = this.logsConsoleLastGTimeById.get(logs.id);
|
|
552
|
+
this.logsConsoleLastGTimeById.set(logs.id, event.timeMs);
|
|
553
|
+
if (prevG !== undefined && event.timeMs - prevG <= 500) {
|
|
554
|
+
this.logsConsoleLastGTimeById.delete(logs.id);
|
|
555
|
+
if (logs.scrollTop !== 0) {
|
|
556
|
+
logs.onScroll(0);
|
|
557
|
+
return ROUTE_RENDER;
|
|
558
|
+
}
|
|
559
|
+
return ROUTE_NO_RENDER;
|
|
560
|
+
}
|
|
561
|
+
return ROUTE_NO_RENDER;
|
|
562
|
+
}
|
|
563
|
+
if (!isShift && key === 67 /* C */ && logs.onClear) {
|
|
564
|
+
logs.onClear();
|
|
565
|
+
return ROUTE_RENDER;
|
|
566
|
+
}
|
|
567
|
+
if (key === ZR_KEY_ENTER && logs.onEntryToggle) {
|
|
568
|
+
const idx = Math.max(0, Math.min(filtered.length - 1, logs.scrollTop));
|
|
569
|
+
const entry = filtered[idx];
|
|
570
|
+
if (entry) {
|
|
571
|
+
const expanded = logs.expandedEntries?.includes(entry.id) ?? false;
|
|
572
|
+
logs.onEntryToggle(entry.id, !expanded);
|
|
573
|
+
return ROUTE_RENDER;
|
|
574
|
+
}
|
|
575
|
+
return ROUTE_NO_RENDER;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
// Diff viewer routing (GitHub issue #136)
|
|
579
|
+
const diff = this.diffViewerById.get(focusedId);
|
|
580
|
+
if (diff) {
|
|
581
|
+
const isShift = (event.mods & ZR_MOD_SHIFT) !== 0;
|
|
582
|
+
const key = event.key;
|
|
583
|
+
const hunkCount = diff.diff.hunks.length;
|
|
584
|
+
const curFocused = this.diffViewerFocusedHunkById.get(diff.id) ?? diff.focusedHunk ?? 0;
|
|
585
|
+
const focusedHunk = Math.max(0, Math.min(hunkCount - 1, curFocused));
|
|
586
|
+
const isNext = key === ZR_KEY_DOWN || (!isShift && key === 74) /* J */;
|
|
587
|
+
const isPrev = key === ZR_KEY_UP || (!isShift && key === 75) /* K */;
|
|
588
|
+
if (isNext || isPrev) {
|
|
589
|
+
const nextFocused = navigateHunk(focusedHunk, isNext ? "next" : "prev", hunkCount);
|
|
590
|
+
this.diffViewerFocusedHunkById.set(diff.id, nextFocused);
|
|
591
|
+
diff.onScroll(getHunkScrollPosition(nextFocused, diff.diff.hunks));
|
|
592
|
+
return ROUTE_RENDER;
|
|
593
|
+
}
|
|
594
|
+
if (key === ZR_KEY_ENTER) {
|
|
595
|
+
const base = this.diffViewerExpandedHunksById.get(diff.id) ??
|
|
596
|
+
new Set(diff.expandedHunks ?? []);
|
|
597
|
+
const next = new Set(base);
|
|
598
|
+
const expanded = next.has(focusedHunk);
|
|
599
|
+
if (expanded)
|
|
600
|
+
next.delete(focusedHunk);
|
|
601
|
+
else
|
|
602
|
+
next.add(focusedHunk);
|
|
603
|
+
this.diffViewerExpandedHunksById.set(diff.id, next);
|
|
604
|
+
diff.onHunkToggle?.(focusedHunk, !expanded);
|
|
605
|
+
return ROUTE_RENDER;
|
|
606
|
+
}
|
|
607
|
+
if (!isShift && key === 83 /* S */ && diff.onStageHunk) {
|
|
608
|
+
diff.onStageHunk(focusedHunk);
|
|
609
|
+
return ROUTE_RENDER;
|
|
610
|
+
}
|
|
611
|
+
if (!isShift && key === 85 /* U */ && diff.onUnstageHunk) {
|
|
612
|
+
diff.onUnstageHunk(focusedHunk);
|
|
613
|
+
return ROUTE_RENDER;
|
|
614
|
+
}
|
|
615
|
+
if (!isShift && key === 65 /* A */ && diff.onApplyHunk) {
|
|
616
|
+
diff.onApplyHunk(focusedHunk);
|
|
617
|
+
return ROUTE_RENDER;
|
|
618
|
+
}
|
|
619
|
+
if (!isShift && key === 82 /* R */ && diff.onRevertHunk) {
|
|
620
|
+
diff.onRevertHunk(focusedHunk);
|
|
621
|
+
return ROUTE_RENDER;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
// Virtual list routing
|
|
625
|
+
const vlist = this.virtualListById.get(focusedId);
|
|
626
|
+
if (vlist) {
|
|
627
|
+
const state = this.virtualListStore.get(vlist.id);
|
|
628
|
+
const r = routeVirtualListKey(event, {
|
|
629
|
+
virtualListId: vlist.id,
|
|
630
|
+
items: vlist.items,
|
|
631
|
+
itemHeight: vlist.itemHeight,
|
|
632
|
+
state,
|
|
633
|
+
keyboardNavigation: vlist.keyboardNavigation !== false,
|
|
634
|
+
wrapAround: vlist.wrapAround === true,
|
|
635
|
+
});
|
|
636
|
+
let changed = false;
|
|
637
|
+
if (r.nextSelectedIndex !== undefined || r.nextScrollTop !== undefined) {
|
|
638
|
+
const patch = {};
|
|
639
|
+
if (r.nextSelectedIndex !== undefined)
|
|
640
|
+
patch.selectedIndex = r.nextSelectedIndex;
|
|
641
|
+
if (r.nextScrollTop !== undefined)
|
|
642
|
+
patch.scrollTop = r.nextScrollTop;
|
|
643
|
+
this.virtualListStore.set(vlist.id, patch);
|
|
644
|
+
changed = true;
|
|
645
|
+
}
|
|
646
|
+
if (r.action && vlist.onSelect) {
|
|
647
|
+
const item = vlist.items[r.action.index];
|
|
648
|
+
if (item !== undefined)
|
|
649
|
+
vlist.onSelect(item, r.action.index);
|
|
650
|
+
changed = true;
|
|
651
|
+
}
|
|
652
|
+
if (changed)
|
|
653
|
+
return ROUTE_RENDER;
|
|
654
|
+
}
|
|
655
|
+
// Table routing
|
|
656
|
+
const table = this.tableById.get(focusedId);
|
|
657
|
+
if (table) {
|
|
658
|
+
const rowHeight = table.rowHeight ?? 1;
|
|
659
|
+
const tableCache = this.tableRenderCacheById.get(table.id);
|
|
660
|
+
const rowKeys = tableCache?.rowKeys ?? table.data.map((row, i) => table.getRowKey(row, i));
|
|
661
|
+
const state = this.tableStore.get(table.id);
|
|
662
|
+
const r = routeTableKey(event, {
|
|
663
|
+
tableId: table.id,
|
|
664
|
+
rowKeys,
|
|
665
|
+
...(tableCache?.rowKeyToIndex ? { rowKeyToIndex: tableCache.rowKeyToIndex } : {}),
|
|
666
|
+
data: table.data,
|
|
667
|
+
rowHeight,
|
|
668
|
+
state,
|
|
669
|
+
selection: (table.selection ?? EMPTY_STRING_ARRAY),
|
|
670
|
+
selectionMode: table.selectionMode ?? "none",
|
|
671
|
+
keyboardNavigation: true,
|
|
672
|
+
});
|
|
673
|
+
if (r.consumed) {
|
|
674
|
+
if (r.nextFocusedRowIndex !== undefined ||
|
|
675
|
+
r.nextScrollTop !== undefined ||
|
|
676
|
+
r.nextLastClickedKey !== undefined) {
|
|
677
|
+
const patch = {};
|
|
678
|
+
if (r.nextFocusedRowIndex !== undefined)
|
|
679
|
+
patch.focusedRowIndex = r.nextFocusedRowIndex;
|
|
680
|
+
if (r.nextScrollTop !== undefined)
|
|
681
|
+
patch.scrollTop = r.nextScrollTop;
|
|
682
|
+
if (r.nextLastClickedKey !== undefined)
|
|
683
|
+
patch.lastClickedKey = r.nextLastClickedKey;
|
|
684
|
+
this.tableStore.set(table.id, patch);
|
|
685
|
+
}
|
|
686
|
+
if (r.nextSelection !== undefined && table.onSelectionChange) {
|
|
687
|
+
table.onSelectionChange(r.nextSelection);
|
|
688
|
+
}
|
|
689
|
+
if (r.action && table.onRowPress) {
|
|
690
|
+
const row = table.data[r.action.rowIndex];
|
|
691
|
+
if (row !== undefined)
|
|
692
|
+
table.onRowPress(row, r.action.rowIndex);
|
|
693
|
+
}
|
|
694
|
+
return ROUTE_RENDER;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
// Tree routing
|
|
698
|
+
const tree = this.treeById.get(focusedId);
|
|
699
|
+
if (tree) {
|
|
700
|
+
const state = this.treeStore.get(tree.id);
|
|
701
|
+
const expandedSet = state.expandedSetRef === tree.expanded && state.expandedSet
|
|
702
|
+
? state.expandedSet
|
|
703
|
+
: new Set(tree.expanded);
|
|
704
|
+
if (state.expandedSetRef !== tree.expanded) {
|
|
705
|
+
this.treeStore.set(tree.id, { expandedSetRef: tree.expanded, expandedSet });
|
|
706
|
+
}
|
|
707
|
+
const loaded = this.loadedTreeChildrenByTreeId.get(tree.id);
|
|
708
|
+
const getChildrenRaw = tree.getChildren;
|
|
709
|
+
const getKey = tree.getKey;
|
|
710
|
+
const getChildren = loaded
|
|
711
|
+
? (n) => {
|
|
712
|
+
const k = getKey(n);
|
|
713
|
+
const cached = loaded.get(k);
|
|
714
|
+
return cached ?? getChildrenRaw?.(n);
|
|
715
|
+
}
|
|
716
|
+
: getChildrenRaw;
|
|
717
|
+
const cached = state.flatCache;
|
|
718
|
+
const canReuseFlatCache = cached &&
|
|
719
|
+
cached.kind === "tree" &&
|
|
720
|
+
cached.dataRef === tree.data &&
|
|
721
|
+
cached.expandedRef === tree.expanded &&
|
|
722
|
+
cached.getKeyRef === tree.getKey &&
|
|
723
|
+
cached.getChildrenRef === tree.getChildren &&
|
|
724
|
+
cached.hasChildrenRef === tree.hasChildren &&
|
|
725
|
+
cached.loadedRef === loaded;
|
|
726
|
+
const flatNodes = canReuseFlatCache
|
|
727
|
+
? cached.flatNodes
|
|
728
|
+
: flattenTree(tree.data, getKey, getChildren, tree.hasChildren, tree.expanded, expandedSet);
|
|
729
|
+
if (!canReuseFlatCache) {
|
|
730
|
+
this.treeStore.set(tree.id, {
|
|
731
|
+
flatCache: Object.freeze({
|
|
732
|
+
kind: "tree",
|
|
733
|
+
dataRef: tree.data,
|
|
734
|
+
expandedRef: tree.expanded,
|
|
735
|
+
loadedRef: loaded,
|
|
736
|
+
getKeyRef: tree.getKey,
|
|
737
|
+
getChildrenRef: tree.getChildren,
|
|
738
|
+
hasChildrenRef: tree.hasChildren,
|
|
739
|
+
flatNodes: flatNodes,
|
|
740
|
+
}),
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
const r = routeTreeKey(event, {
|
|
744
|
+
treeId: tree.id,
|
|
745
|
+
flatNodes,
|
|
746
|
+
expanded: tree.expanded,
|
|
747
|
+
state,
|
|
748
|
+
keyboardNavigation: true,
|
|
749
|
+
});
|
|
750
|
+
if (r.consumed) {
|
|
751
|
+
if (r.nextFocusedKey !== undefined || r.nextScrollTop !== undefined) {
|
|
752
|
+
const patch = {};
|
|
753
|
+
if (r.nextFocusedKey !== undefined)
|
|
754
|
+
patch.focusedKey = r.nextFocusedKey;
|
|
755
|
+
if (r.nextScrollTop !== undefined)
|
|
756
|
+
patch.scrollTop = r.nextScrollTop;
|
|
757
|
+
this.treeStore.set(tree.id, patch);
|
|
758
|
+
}
|
|
759
|
+
if (r.nodeToSelect && tree.onSelect) {
|
|
760
|
+
const found = flatNodes.find((n) => n.key === r.nodeToSelect);
|
|
761
|
+
if (found)
|
|
762
|
+
tree.onSelect(found.node);
|
|
763
|
+
}
|
|
764
|
+
if (r.nodeToActivate && tree.onActivate) {
|
|
765
|
+
const found = flatNodes.find((n) => n.key === r.nodeToActivate);
|
|
766
|
+
if (found)
|
|
767
|
+
tree.onActivate(found.node);
|
|
768
|
+
}
|
|
769
|
+
if (r.nodeToLoad && tree.loadChildren) {
|
|
770
|
+
const nodeKey = r.nodeToLoad;
|
|
771
|
+
const alreadyLoaded = this.loadedTreeChildrenByTreeId.get(tree.id)?.get(nodeKey) !== undefined;
|
|
772
|
+
const alreadyLoading = state.loadingKeys.has(nodeKey);
|
|
773
|
+
const found = flatNodes.find((n) => n.key === nodeKey);
|
|
774
|
+
if (!alreadyLoaded && !alreadyLoading && found) {
|
|
775
|
+
this.treeStore.startLoading(tree.id, nodeKey);
|
|
776
|
+
const token = this.nextTreeLoadToken++;
|
|
777
|
+
const tokenKey = `${tree.id}\u0000${nodeKey}`;
|
|
778
|
+
this.treeLoadTokenByTreeAndKey.set(tokenKey, token);
|
|
779
|
+
void tree.loadChildren(found.node).then((children) => {
|
|
780
|
+
if (this.treeLoadTokenByTreeAndKey.get(tokenKey) !== token)
|
|
781
|
+
return;
|
|
782
|
+
this.treeLoadTokenByTreeAndKey.delete(tokenKey);
|
|
783
|
+
const prev = this.loadedTreeChildrenByTreeId.get(tree.id);
|
|
784
|
+
const next = new Map(prev ? Array.from(prev.entries()) : []);
|
|
785
|
+
next.set(nodeKey, Object.freeze(children.slice()));
|
|
786
|
+
this.loadedTreeChildrenByTreeId.set(tree.id, next);
|
|
787
|
+
this.treeStore.finishLoading(tree.id, nodeKey);
|
|
788
|
+
this.requestRender();
|
|
789
|
+
}, () => {
|
|
790
|
+
if (this.treeLoadTokenByTreeAndKey.get(tokenKey) !== token)
|
|
791
|
+
return;
|
|
792
|
+
this.treeLoadTokenByTreeAndKey.delete(tokenKey);
|
|
793
|
+
this.treeStore.finishLoading(tree.id, nodeKey);
|
|
794
|
+
this.requestRender();
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
if (r.nextExpanded !== undefined) {
|
|
799
|
+
// Best-effort: detect toggled keys and invoke onToggle for each diff.
|
|
800
|
+
const prev = new Set(tree.expanded);
|
|
801
|
+
const next = new Set(r.nextExpanded);
|
|
802
|
+
const diffs = [];
|
|
803
|
+
for (const k of next)
|
|
804
|
+
if (!prev.has(k))
|
|
805
|
+
diffs.push(k);
|
|
806
|
+
for (const k of prev)
|
|
807
|
+
if (!next.has(k))
|
|
808
|
+
diffs.push(k);
|
|
809
|
+
for (const k of diffs) {
|
|
810
|
+
const found = flatNodes.find((n) => n.key === k);
|
|
811
|
+
if (found)
|
|
812
|
+
tree.onToggle(found.node, next.has(k));
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
return ROUTE_RENDER;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
// Select routing (simple: arrow keys cycle; Enter/Space cycles)
|
|
819
|
+
const select = this.selectById.get(focusedId);
|
|
820
|
+
if (select && select.disabled !== true && select.options.length > 0) {
|
|
821
|
+
const KEY_UP = 20;
|
|
822
|
+
const KEY_DOWN = 21;
|
|
823
|
+
const KEY_ENTER = 2;
|
|
824
|
+
const KEY_SPACE = 32;
|
|
825
|
+
const dir = event.key === KEY_UP
|
|
826
|
+
? -1
|
|
827
|
+
: event.key === KEY_DOWN
|
|
828
|
+
? 1
|
|
829
|
+
: event.key === KEY_ENTER || event.key === KEY_SPACE
|
|
830
|
+
? 1
|
|
831
|
+
: 0;
|
|
832
|
+
if (dir !== 0 && select.onChange) {
|
|
833
|
+
const opts = select.options.filter((o) => o.disabled !== true);
|
|
834
|
+
if (opts.length > 0) {
|
|
835
|
+
const idx = opts.findIndex((o) => o.value === select.value);
|
|
836
|
+
const nextIdx = idx < 0 ? 0 : (idx + dir + opts.length) % opts.length;
|
|
837
|
+
const next = opts[nextIdx];
|
|
838
|
+
if (next && next.value !== select.value) {
|
|
839
|
+
select.onChange(next.value);
|
|
840
|
+
return ROUTE_RENDER;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
// Checkbox routing (Space/Enter toggles)
|
|
846
|
+
const checkbox = this.checkboxById.get(focusedId);
|
|
847
|
+
if (checkbox && checkbox.disabled !== true && checkbox.onChange) {
|
|
848
|
+
const KEY_ENTER = 2;
|
|
849
|
+
const KEY_SPACE = 32;
|
|
850
|
+
if (event.key === KEY_ENTER || event.key === KEY_SPACE) {
|
|
851
|
+
checkbox.onChange(!checkbox.checked);
|
|
852
|
+
return ROUTE_RENDER;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
// Radio group routing (arrow keys change selection)
|
|
856
|
+
const radio = this.radioGroupById.get(focusedId);
|
|
857
|
+
if (radio && radio.disabled !== true && radio.onChange) {
|
|
858
|
+
const KEY_UP = 20;
|
|
859
|
+
const KEY_DOWN = 21;
|
|
860
|
+
const KEY_LEFT = 22;
|
|
861
|
+
const KEY_RIGHT = 23;
|
|
862
|
+
const isHorizontal = radio.direction === "horizontal";
|
|
863
|
+
const dir = (isHorizontal && event.key === KEY_LEFT) || (!isHorizontal && event.key === KEY_UP)
|
|
864
|
+
? -1
|
|
865
|
+
: (isHorizontal && event.key === KEY_RIGHT) || (!isHorizontal && event.key === KEY_DOWN)
|
|
866
|
+
? 1
|
|
867
|
+
: 0;
|
|
868
|
+
if (dir !== 0) {
|
|
869
|
+
const opts = radio.options.filter((o) => o.disabled !== true);
|
|
870
|
+
if (opts.length > 0) {
|
|
871
|
+
const idx = opts.findIndex((o) => o.value === radio.value);
|
|
872
|
+
const nextIdx = idx < 0 ? 0 : (idx + dir + opts.length) % opts.length;
|
|
873
|
+
const next = opts[nextIdx];
|
|
874
|
+
if (next && next.value !== radio.value) {
|
|
875
|
+
radio.onChange(next.value);
|
|
876
|
+
return ROUTE_RENDER;
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
// Mouse wheel for virtual list (prefer list under cursor; fallback to focused list).
|
|
883
|
+
if (event.kind === "mouse" && event.mouseKind === 5) {
|
|
884
|
+
const targetId = mouseTargetId ?? focusedId;
|
|
885
|
+
if (targetId === null)
|
|
886
|
+
return ROUTE_NO_RENDER;
|
|
887
|
+
const vlist = this.virtualListById.get(targetId);
|
|
888
|
+
if (vlist) {
|
|
889
|
+
const state = this.virtualListStore.get(vlist.id);
|
|
890
|
+
const totalHeight = getTotalHeight(vlist.items, vlist.itemHeight);
|
|
891
|
+
const r = routeVirtualListWheel(event, {
|
|
892
|
+
scrollTop: state.scrollTop,
|
|
893
|
+
totalHeight,
|
|
894
|
+
viewportHeight: state.viewportHeight,
|
|
895
|
+
});
|
|
896
|
+
if (r.nextScrollTop !== undefined) {
|
|
897
|
+
this.virtualListStore.set(vlist.id, { scrollTop: r.nextScrollTop });
|
|
898
|
+
return ROUTE_RENDER;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
if (focusedId !== null) {
|
|
902
|
+
const editor = this.codeEditorById.get(focusedId);
|
|
903
|
+
if (editor) {
|
|
904
|
+
const rect = this.rectById.get(editor.id) ?? null;
|
|
905
|
+
const viewportHeight = rect ? Math.max(1, rect.h) : 1;
|
|
906
|
+
const maxScrollTop = Math.max(0, editor.lines.length - viewportHeight);
|
|
907
|
+
const nextScrollTop = Math.max(0, Math.min(maxScrollTop, editor.scrollTop + event.wheelY * 3));
|
|
908
|
+
const nextScrollLeft = Math.max(0, editor.scrollLeft + event.wheelX * 3);
|
|
909
|
+
if (nextScrollTop !== editor.scrollTop || nextScrollLeft !== editor.scrollLeft) {
|
|
910
|
+
editor.onScroll(nextScrollTop, nextScrollLeft);
|
|
911
|
+
return ROUTE_RENDER;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
const logs = this.logsConsoleById.get(focusedId);
|
|
915
|
+
if (logs) {
|
|
916
|
+
const rect = this.rectById.get(logs.id) ?? null;
|
|
917
|
+
const viewportHeight = rect ? Math.max(1, rect.h) : 1;
|
|
918
|
+
const cached = this.logsConsoleRenderCacheById.get(logs.id);
|
|
919
|
+
const filteredLen = cached?.filtered.length ??
|
|
920
|
+
applyFilters(logs.entries, logs.levelFilter, logs.sourceFilter, logs.searchQuery)
|
|
921
|
+
.length;
|
|
922
|
+
const maxScroll = Math.max(0, filteredLen - viewportHeight);
|
|
923
|
+
const nextScrollTop = Math.max(0, Math.min(maxScroll, logs.scrollTop + event.wheelY * 3));
|
|
924
|
+
if (nextScrollTop !== logs.scrollTop) {
|
|
925
|
+
logs.onScroll(nextScrollTop);
|
|
926
|
+
return ROUTE_RENDER;
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
const diff = this.diffViewerById.get(focusedId);
|
|
930
|
+
if (diff) {
|
|
931
|
+
const rect = this.rectById.get(diff.id) ?? null;
|
|
932
|
+
const viewportHeight = rect ? Math.max(1, rect.h) : 1;
|
|
933
|
+
let totalLines = 0;
|
|
934
|
+
for (const h of diff.diff.hunks) {
|
|
935
|
+
if (!h)
|
|
936
|
+
continue;
|
|
937
|
+
totalLines += 1 + h.lines.length;
|
|
938
|
+
}
|
|
939
|
+
const maxScroll = Math.max(0, totalLines - viewportHeight);
|
|
940
|
+
const nextScrollTop = Math.max(0, Math.min(maxScroll, diff.scrollTop + event.wheelY * 3));
|
|
941
|
+
if (nextScrollTop !== diff.scrollTop) {
|
|
942
|
+
diff.onScroll(nextScrollTop);
|
|
943
|
+
return ROUTE_RENDER;
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
// Text/paste input for command palette and code editor (docs/18 text events are distinct from keys).
|
|
949
|
+
if ((event.kind === "text" || event.kind === "paste") && this.focusState.focusedId !== null) {
|
|
950
|
+
const focusedId = this.focusState.focusedId;
|
|
951
|
+
const palette = this.commandPaletteById.get(focusedId);
|
|
952
|
+
if (palette?.open === true) {
|
|
953
|
+
const append = event.kind === "text"
|
|
954
|
+
? event.codepoint >= 0 && event.codepoint <= 0x10ffff
|
|
955
|
+
? String.fromCodePoint(event.codepoint)
|
|
956
|
+
: ""
|
|
957
|
+
: UTF8_DECODER.decode(event.bytes);
|
|
958
|
+
if (append.length > 0) {
|
|
959
|
+
palette.onQueryChange(palette.query + append);
|
|
960
|
+
palette.onSelectionChange?.(0);
|
|
961
|
+
return ROUTE_RENDER;
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
const editor = this.codeEditorById.get(focusedId);
|
|
965
|
+
if (editor && editor.readOnly !== true) {
|
|
966
|
+
const insert = event.kind === "text"
|
|
967
|
+
? event.codepoint >= 0 && event.codepoint <= 0x10ffff
|
|
968
|
+
? String.fromCodePoint(event.codepoint)
|
|
969
|
+
: ""
|
|
970
|
+
: UTF8_DECODER.decode(event.bytes);
|
|
971
|
+
if (insert.length > 0) {
|
|
972
|
+
const base = editor.selection ? deleteRange(editor.lines, editor.selection) : null;
|
|
973
|
+
const next = insertText(base ? base.lines : editor.lines, base ? base.cursor : editor.cursor, insert);
|
|
974
|
+
if (editor.selection !== null)
|
|
975
|
+
editor.onSelectionChange(null);
|
|
976
|
+
editor.onChange(next.lines, next.cursor);
|
|
977
|
+
return ROUTE_RENDER;
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
// Mouse click for virtual list:
|
|
982
|
+
// - on down: update selectedIndex
|
|
983
|
+
// - on up: activate onSelect if released on the same item
|
|
984
|
+
if (event.kind === "mouse" && (event.mouseKind === 3 || event.mouseKind === 4)) {
|
|
985
|
+
const targetId = mouseTargetId;
|
|
986
|
+
if (targetId !== null) {
|
|
987
|
+
const vlist = this.virtualListById.get(targetId);
|
|
988
|
+
const rect = this.rectById.get(targetId);
|
|
989
|
+
if (vlist && rect) {
|
|
990
|
+
const state = this.virtualListStore.get(targetId);
|
|
991
|
+
const localY = event.y - rect.y;
|
|
992
|
+
const inBounds = localY >= 0 && localY < rect.h;
|
|
993
|
+
const computeIndex = () => {
|
|
994
|
+
if (!inBounds)
|
|
995
|
+
return null;
|
|
996
|
+
const yInContent = state.scrollTop + localY;
|
|
997
|
+
if (yInContent < 0)
|
|
998
|
+
return null;
|
|
999
|
+
if (vlist.items.length === 0)
|
|
1000
|
+
return null;
|
|
1001
|
+
if (typeof vlist.itemHeight === "number") {
|
|
1002
|
+
const h = vlist.itemHeight;
|
|
1003
|
+
if (h <= 0)
|
|
1004
|
+
return null;
|
|
1005
|
+
return Math.floor(yInContent / h);
|
|
1006
|
+
}
|
|
1007
|
+
const { itemOffsets } = computeVisibleRange(vlist.items, vlist.itemHeight, 0, Number.MAX_SAFE_INTEGER, 0);
|
|
1008
|
+
let lo = 0;
|
|
1009
|
+
let hi = vlist.items.length - 1;
|
|
1010
|
+
while (lo <= hi) {
|
|
1011
|
+
const mid = (lo + hi) >>> 1;
|
|
1012
|
+
const start = itemOffsets[mid] ?? 0;
|
|
1013
|
+
const end = itemOffsets[mid + 1] ?? start;
|
|
1014
|
+
if (yInContent < start) {
|
|
1015
|
+
hi = mid - 1;
|
|
1016
|
+
}
|
|
1017
|
+
else if (yInContent >= end) {
|
|
1018
|
+
lo = mid + 1;
|
|
1019
|
+
}
|
|
1020
|
+
else {
|
|
1021
|
+
return mid;
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
return null;
|
|
1025
|
+
};
|
|
1026
|
+
if (event.mouseKind === 3) {
|
|
1027
|
+
const idx0 = computeIndex();
|
|
1028
|
+
if (idx0 !== null) {
|
|
1029
|
+
const idx = Math.max(0, Math.min(vlist.items.length - 1, idx0));
|
|
1030
|
+
const prev = state.selectedIndex;
|
|
1031
|
+
this.virtualListStore.set(targetId, { selectedIndex: idx });
|
|
1032
|
+
this.pressedVirtualList = Object.freeze({ id: targetId, index: idx });
|
|
1033
|
+
if (idx !== prev)
|
|
1034
|
+
localNeedsRender = true;
|
|
1035
|
+
}
|
|
1036
|
+
else {
|
|
1037
|
+
this.pressedVirtualList = null;
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
else {
|
|
1041
|
+
const idx0 = computeIndex();
|
|
1042
|
+
const pressed = this.pressedVirtualList;
|
|
1043
|
+
this.pressedVirtualList = null;
|
|
1044
|
+
if (idx0 !== null && pressed && pressed.id === targetId) {
|
|
1045
|
+
const idx = Math.max(0, Math.min(vlist.items.length - 1, idx0));
|
|
1046
|
+
if (idx === pressed.index) {
|
|
1047
|
+
if (vlist.onSelect) {
|
|
1048
|
+
const item = vlist.items[idx];
|
|
1049
|
+
if (item !== undefined)
|
|
1050
|
+
vlist.onSelect(item, idx);
|
|
1051
|
+
}
|
|
1052
|
+
localNeedsRender = true;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
else if (event.mouseKind === 4) {
|
|
1058
|
+
this.pressedVirtualList = null;
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
else if (event.mouseKind === 4) {
|
|
1062
|
+
this.pressedVirtualList = null;
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
const res = event.kind === "key"
|
|
1066
|
+
? routeKeyWithZones(event, {
|
|
1067
|
+
focusedId: this.focusState.focusedId,
|
|
1068
|
+
activeZoneId: this.focusState.activeZoneId,
|
|
1069
|
+
focusList: this.focusList,
|
|
1070
|
+
zones: this.focusState.zones,
|
|
1071
|
+
traps: this.traps,
|
|
1072
|
+
trapStack: this.focusState.trapStack,
|
|
1073
|
+
enabledById,
|
|
1074
|
+
pressableIds: this.pressableIds,
|
|
1075
|
+
})
|
|
1076
|
+
: event.kind === "mouse"
|
|
1077
|
+
? routeMouse(event, {
|
|
1078
|
+
pressedId: this.pressedId,
|
|
1079
|
+
hitTestTargetId: mouseTargetId,
|
|
1080
|
+
enabledById,
|
|
1081
|
+
pressableIds: this.pressableIds,
|
|
1082
|
+
})
|
|
1083
|
+
: EMPTY_ROUTING;
|
|
1084
|
+
if (res.nextPressedId !== undefined)
|
|
1085
|
+
this.pressedId = res.nextPressedId;
|
|
1086
|
+
if (res.nextZoneId !== undefined) {
|
|
1087
|
+
this.focusState = Object.freeze({ ...this.focusState, activeZoneId: res.nextZoneId ?? null });
|
|
1088
|
+
}
|
|
1089
|
+
if (res.nextFocusedId !== undefined) {
|
|
1090
|
+
const nextFocused = res.nextFocusedId;
|
|
1091
|
+
let nextZoneId = this.focusState.activeZoneId;
|
|
1092
|
+
if (nextFocused !== null) {
|
|
1093
|
+
for (const [zoneId, zone] of this.focusState.zones) {
|
|
1094
|
+
if (zone.focusableIds.includes(nextFocused)) {
|
|
1095
|
+
nextZoneId = zoneId;
|
|
1096
|
+
break;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
const nextLastFocusedByZone = new Map(this.focusState.lastFocusedByZone);
|
|
1101
|
+
if (nextFocused !== null && nextZoneId !== null) {
|
|
1102
|
+
nextLastFocusedByZone.set(nextZoneId, nextFocused);
|
|
1103
|
+
}
|
|
1104
|
+
this.focusState = Object.freeze({
|
|
1105
|
+
...this.focusState,
|
|
1106
|
+
focusedId: nextFocused,
|
|
1107
|
+
activeZoneId: nextZoneId,
|
|
1108
|
+
lastFocusedByZone: nextLastFocusedByZone,
|
|
1109
|
+
});
|
|
1110
|
+
}
|
|
1111
|
+
const didFocusChange = this.focusState.focusedId !== prevFocusedId;
|
|
1112
|
+
const needsRender = didFocusChange || this.pressedId !== prevPressedId || localNeedsRender;
|
|
1113
|
+
if (didFocusChange && prevFocusedId !== null) {
|
|
1114
|
+
const prevInput = this.inputById.get(prevFocusedId);
|
|
1115
|
+
if (prevInput?.onBlur)
|
|
1116
|
+
prevInput.onBlur();
|
|
1117
|
+
}
|
|
1118
|
+
if (res.action) {
|
|
1119
|
+
if (res.action.action === "press") {
|
|
1120
|
+
const btn = this.buttonById.get(res.action.id);
|
|
1121
|
+
if (btn?.onPress)
|
|
1122
|
+
btn.onPress();
|
|
1123
|
+
}
|
|
1124
|
+
return Object.freeze({ needsRender, action: res.action });
|
|
1125
|
+
}
|
|
1126
|
+
// Input editing (docs/18): focused enabled Input is the routing target for key/text/paste events.
|
|
1127
|
+
if (event.kind === "key" || event.kind === "text" || event.kind === "paste") {
|
|
1128
|
+
const focusedId = this.focusState.focusedId;
|
|
1129
|
+
if (focusedId !== null && enabledById.get(focusedId) === true) {
|
|
1130
|
+
const meta = this.inputById.get(focusedId);
|
|
1131
|
+
if (meta) {
|
|
1132
|
+
const instanceId = meta.instanceId;
|
|
1133
|
+
const value = this.inputWorkingValueByInstanceId.get(instanceId) ?? meta.value;
|
|
1134
|
+
const cursor = this.inputCursorByInstanceId.get(instanceId) ?? value.length;
|
|
1135
|
+
const edit = applyInputEditEvent(event, { id: focusedId, value, cursor });
|
|
1136
|
+
if (edit) {
|
|
1137
|
+
this.inputWorkingValueByInstanceId.set(instanceId, edit.nextValue);
|
|
1138
|
+
this.inputCursorByInstanceId.set(instanceId, edit.nextCursor);
|
|
1139
|
+
if (edit.action) {
|
|
1140
|
+
if (meta.onInput)
|
|
1141
|
+
meta.onInput(edit.action.value, edit.action.cursor);
|
|
1142
|
+
return Object.freeze({ needsRender, action: edit.action });
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
return Object.freeze({ needsRender });
|
|
1149
|
+
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Execute view function, commit tree, compute layout, and render to drawlist.
|
|
1152
|
+
*
|
|
1153
|
+
* Pipeline:
|
|
1154
|
+
* 1. Call viewFn(snapshot) to get VNode tree
|
|
1155
|
+
* 2. Commit VNode tree (reconciliation, instance allocation)
|
|
1156
|
+
* 3. Compute layout for viewport dimensions
|
|
1157
|
+
* 4. Finalize focus state for committed tree
|
|
1158
|
+
* 5. Render tree to drawlist
|
|
1159
|
+
* 6. Submit drawlist to backend
|
|
1160
|
+
*
|
|
1161
|
+
* @param viewFn - User view function returning VNode tree
|
|
1162
|
+
* @param snapshot - Current application state (read-only)
|
|
1163
|
+
* @param viewport - Terminal dimensions
|
|
1164
|
+
* @param hooks - Lifecycle hooks for render tracking
|
|
1165
|
+
* @returns Success with in-flight promise, or error with code/detail
|
|
1166
|
+
*/
|
|
1167
|
+
submitFrame(viewFn, snapshot, viewport, theme, hooks, plan = { commit: true, layout: true, checkLayoutStability: true }) {
|
|
1168
|
+
if (!isI32NonNegative(viewport.cols) || !isI32NonNegative(viewport.rows)) {
|
|
1169
|
+
return {
|
|
1170
|
+
ok: false,
|
|
1171
|
+
code: "ZRUI_INVALID_PROPS",
|
|
1172
|
+
detail: `viewport must be int32 cols/rows >= 0 (got cols=${String(viewport.cols)}, rows=${String(viewport.rows)})`,
|
|
1173
|
+
};
|
|
1174
|
+
}
|
|
1175
|
+
this.builder.reset();
|
|
1176
|
+
let entered = false;
|
|
1177
|
+
try {
|
|
1178
|
+
hooks.enterRender();
|
|
1179
|
+
entered = true;
|
|
1180
|
+
const doCommit = plan.commit || this.committedRoot === null;
|
|
1181
|
+
// Layout is no longer an unconditional consequence of commit. We rerun
|
|
1182
|
+
// layout when explicitly requested (resize/layout dirty), bootstrap lacks
|
|
1183
|
+
// a tree, or committed layout signatures changed.
|
|
1184
|
+
let doLayout = plan.layout || this.layoutTree === null;
|
|
1185
|
+
let commitRes = null;
|
|
1186
|
+
let prevFocusedIdBeforeFinalize = null;
|
|
1187
|
+
const hadRoutingWidgets = this.hadRoutingWidgets;
|
|
1188
|
+
let hasRoutingWidgets = hadRoutingWidgets;
|
|
1189
|
+
let didRoutingRebuild = false;
|
|
1190
|
+
if (doCommit) {
|
|
1191
|
+
const viewToken = PERF_DETAIL_ENABLED ? perfMarkStart("view") : 0;
|
|
1192
|
+
const vnode = viewFn(snapshot);
|
|
1193
|
+
if (PERF_DETAIL_ENABLED)
|
|
1194
|
+
perfMarkEnd("view", viewToken);
|
|
1195
|
+
const commitToken = PERF_DETAIL_ENABLED ? perfMarkStart("vnode_commit") : 0;
|
|
1196
|
+
const commitRes0 = commitVNodeTree(this.committedRoot, vnode, {
|
|
1197
|
+
allocator: this.allocator,
|
|
1198
|
+
composite: {
|
|
1199
|
+
registry: this.compositeRegistry,
|
|
1200
|
+
appState: snapshot,
|
|
1201
|
+
onInvalidate: () => this.requestView(),
|
|
1202
|
+
},
|
|
1203
|
+
});
|
|
1204
|
+
if (PERF_DETAIL_ENABLED)
|
|
1205
|
+
perfMarkEnd("vnode_commit", commitToken);
|
|
1206
|
+
if (!commitRes0.ok) {
|
|
1207
|
+
return { ok: false, code: commitRes0.fatal.code, detail: commitRes0.fatal.detail };
|
|
1208
|
+
}
|
|
1209
|
+
commitRes = commitRes0.value;
|
|
1210
|
+
this.committedRoot = commitRes.root;
|
|
1211
|
+
if (!doLayout && plan.checkLayoutStability) {
|
|
1212
|
+
// Detect layout-relevant commit changes (including child order changes)
|
|
1213
|
+
// using per-instance stability signatures.
|
|
1214
|
+
if (updateLayoutStabilitySignatures(this.committedRoot, this._pooledLayoutSigByInstanceId, this._pooledNextLayoutSigByInstanceId, this._pooledRuntimeStack)) {
|
|
1215
|
+
doLayout = true;
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
for (const unmountedId of commitRes.unmountedInstanceIds) {
|
|
1219
|
+
this.inputCursorByInstanceId.delete(unmountedId);
|
|
1220
|
+
this.inputWorkingValueByInstanceId.delete(unmountedId);
|
|
1221
|
+
// Composite instances: invalidate stale closures and run effect cleanups.
|
|
1222
|
+
this.compositeRegistry.incrementGeneration(unmountedId);
|
|
1223
|
+
this.compositeRegistry.delete(unmountedId);
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
if (!this.committedRoot) {
|
|
1227
|
+
return {
|
|
1228
|
+
ok: false,
|
|
1229
|
+
code: "ZRUI_INVALID_PROPS",
|
|
1230
|
+
detail: "widgetRenderer: missing committed root",
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1233
|
+
if (doLayout) {
|
|
1234
|
+
if (doCommit) {
|
|
1235
|
+
// Commit can replace vnode identities; reset cross-frame measure memoization.
|
|
1236
|
+
this._layoutMeasureCache = new WeakMap();
|
|
1237
|
+
}
|
|
1238
|
+
const layoutToken = perfMarkStart("layout");
|
|
1239
|
+
const layoutRes = layout(this.committedRoot.vnode, 0, 0, viewport.cols, viewport.rows, "column", this._layoutMeasureCache);
|
|
1240
|
+
perfMarkEnd("layout", layoutToken);
|
|
1241
|
+
if (!layoutRes.ok) {
|
|
1242
|
+
return { ok: false, code: layoutRes.fatal.code, detail: layoutRes.fatal.detail };
|
|
1243
|
+
}
|
|
1244
|
+
const nextLayoutTree = layoutRes.value;
|
|
1245
|
+
this.layoutTree = nextLayoutTree;
|
|
1246
|
+
// Build a fast instanceId->rect index for overlay routing (modal/layer hit testing),
|
|
1247
|
+
// plus an id->rect map for widget-local interactions (scrolling, divider drags).
|
|
1248
|
+
// Uses pooled collections to avoid per-frame allocations.
|
|
1249
|
+
const layoutIndexesToken = PERF_DETAIL_ENABLED ? perfMarkStart("layout_indexes") : 0;
|
|
1250
|
+
buildLayoutRectIndexes(nextLayoutTree, this.committedRoot, this._pooledRectByInstanceId, this._pooledRectById, this._pooledSplitPaneChildRectsById, this._pooledLayoutStack, this._pooledRuntimeStack);
|
|
1251
|
+
if (PERF_DETAIL_ENABLED)
|
|
1252
|
+
perfMarkEnd("layout_indexes", layoutIndexesToken);
|
|
1253
|
+
this.rectById = this._pooledRectById;
|
|
1254
|
+
this.splitPaneChildRectsById = this._pooledSplitPaneChildRectsById;
|
|
1255
|
+
}
|
|
1256
|
+
if (!this.layoutTree) {
|
|
1257
|
+
return {
|
|
1258
|
+
ok: false,
|
|
1259
|
+
code: "ZRUI_INVALID_PROPS",
|
|
1260
|
+
detail: "widgetRenderer: missing layout tree",
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1263
|
+
if (doCommit) {
|
|
1264
|
+
const metaToken = PERF_DETAIL_ENABLED ? perfMarkStart("metadata_collect") : 0;
|
|
1265
|
+
// Single-pass metadata collection using pooled collector (avoids per-frame allocations)
|
|
1266
|
+
const widgetMeta = this._metadataCollector.collect(this.committedRoot);
|
|
1267
|
+
hasRoutingWidgets = widgetMeta.hasRoutingWidgets;
|
|
1268
|
+
prevFocusedIdBeforeFinalize = this.focusState.focusedId;
|
|
1269
|
+
this.focusState = finalizeFocusWithPreCollectedMetadata(this.focusState, widgetMeta.focusableIds, widgetMeta.zones, widgetMeta.traps);
|
|
1270
|
+
this.baseFocusList = widgetMeta.focusableIds;
|
|
1271
|
+
this.baseEnabledById = widgetMeta.enabledById;
|
|
1272
|
+
this.focusList = widgetMeta.focusableIds;
|
|
1273
|
+
this.enabledById = widgetMeta.enabledById;
|
|
1274
|
+
this.pressableIds = widgetMeta.pressableIds;
|
|
1275
|
+
this.inputById = widgetMeta.inputById;
|
|
1276
|
+
this.traps = widgetMeta.traps;
|
|
1277
|
+
if (PERF_DETAIL_ENABLED)
|
|
1278
|
+
perfMarkEnd("metadata_collect", metaToken);
|
|
1279
|
+
}
|
|
1280
|
+
if (doCommit && (hasRoutingWidgets || hadRoutingWidgets)) {
|
|
1281
|
+
didRoutingRebuild = true;
|
|
1282
|
+
this.hadRoutingWidgets = hasRoutingWidgets;
|
|
1283
|
+
const routingToken = PERF_DETAIL_ENABLED ? perfMarkStart("routing_rebuild") : 0;
|
|
1284
|
+
const getRectForInstance = (instanceId) => this._pooledRectByInstanceId.get(instanceId) ?? ZERO_RECT;
|
|
1285
|
+
// Rebuild complex widget metadata maps (id -> props) for routing.
|
|
1286
|
+
// Use pooled Sets to track previous IDs for GC cleanup detection (avoids per-frame allocations).
|
|
1287
|
+
this._pooledPrevTreeIds.clear();
|
|
1288
|
+
for (const k of this.treeById.keys())
|
|
1289
|
+
this._pooledPrevTreeIds.add(k);
|
|
1290
|
+
this._pooledPrevDropdownIds.clear();
|
|
1291
|
+
for (const k of this.dropdownById.keys())
|
|
1292
|
+
this._pooledPrevDropdownIds.add(k);
|
|
1293
|
+
this._pooledPrevTreeStoreIds.clear();
|
|
1294
|
+
for (const k of this.treeById.keys())
|
|
1295
|
+
this._pooledPrevTreeStoreIds.add(k);
|
|
1296
|
+
for (const k of this.filePickerById.keys())
|
|
1297
|
+
this._pooledPrevTreeStoreIds.add(k);
|
|
1298
|
+
for (const k of this.fileTreeExplorerById.keys())
|
|
1299
|
+
this._pooledPrevTreeStoreIds.add(k);
|
|
1300
|
+
this._pooledPrevCommandPaletteIds.clear();
|
|
1301
|
+
for (const k of this.commandPaletteById.keys())
|
|
1302
|
+
this._pooledPrevCommandPaletteIds.add(k);
|
|
1303
|
+
this._pooledPrevToolApprovalDialogIds.clear();
|
|
1304
|
+
for (const k of this.toolApprovalDialogById.keys())
|
|
1305
|
+
this._pooledPrevToolApprovalDialogIds.add(k);
|
|
1306
|
+
this._pooledPrevDiffViewerIds.clear();
|
|
1307
|
+
for (const k of this.diffViewerById.keys())
|
|
1308
|
+
this._pooledPrevDiffViewerIds.add(k);
|
|
1309
|
+
this._pooledPrevLogsConsoleIds.clear();
|
|
1310
|
+
for (const k of this.logsConsoleById.keys())
|
|
1311
|
+
this._pooledPrevLogsConsoleIds.add(k);
|
|
1312
|
+
this.virtualListById.clear();
|
|
1313
|
+
this.buttonById.clear();
|
|
1314
|
+
this.tableById.clear();
|
|
1315
|
+
this.treeById.clear();
|
|
1316
|
+
this.dropdownById.clear();
|
|
1317
|
+
this.selectById.clear();
|
|
1318
|
+
this.checkboxById.clear();
|
|
1319
|
+
this.radioGroupById.clear();
|
|
1320
|
+
this.commandPaletteById.clear();
|
|
1321
|
+
this.filePickerById.clear();
|
|
1322
|
+
this.fileTreeExplorerById.clear();
|
|
1323
|
+
this.splitPaneById.clear();
|
|
1324
|
+
this.codeEditorById.clear();
|
|
1325
|
+
this.diffViewerById.clear();
|
|
1326
|
+
this.toolApprovalDialogById.clear();
|
|
1327
|
+
this.logsConsoleById.clear();
|
|
1328
|
+
// Rebuild overlay routing state using pooled collections.
|
|
1329
|
+
this.layerRegistry.clear();
|
|
1330
|
+
this._pooledCloseOnEscape.clear();
|
|
1331
|
+
this._pooledCloseOnBackdrop.clear();
|
|
1332
|
+
this._pooledOnClose.clear();
|
|
1333
|
+
this._pooledDropdownStack.length = 0;
|
|
1334
|
+
this._pooledToastContainers.length = 0;
|
|
1335
|
+
let overlaySeq = 0;
|
|
1336
|
+
this._pooledRuntimeStack.length = 0;
|
|
1337
|
+
this._pooledRuntimeStack.push(this.committedRoot);
|
|
1338
|
+
while (this._pooledRuntimeStack.length > 0) {
|
|
1339
|
+
const cur = this._pooledRuntimeStack.pop();
|
|
1340
|
+
if (!cur)
|
|
1341
|
+
continue;
|
|
1342
|
+
const v = cur.vnode;
|
|
1343
|
+
switch (v.kind) {
|
|
1344
|
+
case "dropdown": {
|
|
1345
|
+
const p = v.props;
|
|
1346
|
+
this.dropdownById.set(p.id, p);
|
|
1347
|
+
this._pooledDropdownStack.push(p.id);
|
|
1348
|
+
break;
|
|
1349
|
+
}
|
|
1350
|
+
case "button": {
|
|
1351
|
+
const p = v.props;
|
|
1352
|
+
this.buttonById.set(p.id, p);
|
|
1353
|
+
break;
|
|
1354
|
+
}
|
|
1355
|
+
case "virtualList": {
|
|
1356
|
+
const p = v.props;
|
|
1357
|
+
this.virtualListById.set(p.id, p);
|
|
1358
|
+
break;
|
|
1359
|
+
}
|
|
1360
|
+
case "table": {
|
|
1361
|
+
const p = v.props;
|
|
1362
|
+
this.tableById.set(p.id, p);
|
|
1363
|
+
break;
|
|
1364
|
+
}
|
|
1365
|
+
case "tree": {
|
|
1366
|
+
const p = v.props;
|
|
1367
|
+
this.treeById.set(p.id, p);
|
|
1368
|
+
break;
|
|
1369
|
+
}
|
|
1370
|
+
case "commandPalette": {
|
|
1371
|
+
const p = v.props;
|
|
1372
|
+
this.commandPaletteById.set(p.id, p);
|
|
1373
|
+
break;
|
|
1374
|
+
}
|
|
1375
|
+
case "filePicker": {
|
|
1376
|
+
const p = v.props;
|
|
1377
|
+
this.filePickerById.set(p.id, p);
|
|
1378
|
+
break;
|
|
1379
|
+
}
|
|
1380
|
+
case "fileTreeExplorer": {
|
|
1381
|
+
const p = v.props;
|
|
1382
|
+
this.fileTreeExplorerById.set(p.id, p);
|
|
1383
|
+
break;
|
|
1384
|
+
}
|
|
1385
|
+
case "splitPane": {
|
|
1386
|
+
const p = v.props;
|
|
1387
|
+
this.splitPaneById.set(p.id, p);
|
|
1388
|
+
break;
|
|
1389
|
+
}
|
|
1390
|
+
case "codeEditor": {
|
|
1391
|
+
const p = v.props;
|
|
1392
|
+
this.codeEditorById.set(p.id, p);
|
|
1393
|
+
break;
|
|
1394
|
+
}
|
|
1395
|
+
case "diffViewer": {
|
|
1396
|
+
const p = v.props;
|
|
1397
|
+
this.diffViewerById.set(p.id, p);
|
|
1398
|
+
break;
|
|
1399
|
+
}
|
|
1400
|
+
case "toolApprovalDialog": {
|
|
1401
|
+
const p = v.props;
|
|
1402
|
+
this.toolApprovalDialogById.set(p.id, p);
|
|
1403
|
+
break;
|
|
1404
|
+
}
|
|
1405
|
+
case "logsConsole": {
|
|
1406
|
+
const p = v.props;
|
|
1407
|
+
this.logsConsoleById.set(p.id, p);
|
|
1408
|
+
break;
|
|
1409
|
+
}
|
|
1410
|
+
case "toastContainer": {
|
|
1411
|
+
const p = v.props;
|
|
1412
|
+
const rect = getRectForInstance(cur.instanceId);
|
|
1413
|
+
this._pooledToastContainers.push({ rect, props: p });
|
|
1414
|
+
break;
|
|
1415
|
+
}
|
|
1416
|
+
case "modal": {
|
|
1417
|
+
const p = v.props;
|
|
1418
|
+
const id = typeof p.id === "string" ? p.id : null;
|
|
1419
|
+
if (id) {
|
|
1420
|
+
const rect = getRectForInstance(cur.instanceId);
|
|
1421
|
+
const zIndex = overlaySeq++;
|
|
1422
|
+
const canClose = p.closeOnEscape !== false;
|
|
1423
|
+
this._pooledCloseOnEscape.set(id, canClose);
|
|
1424
|
+
this._pooledCloseOnBackdrop.set(id, p.closeOnBackdrop !== false);
|
|
1425
|
+
const cb = typeof p.onClose === "function" ? p.onClose : undefined;
|
|
1426
|
+
if (cb)
|
|
1427
|
+
this._pooledOnClose.set(id, cb);
|
|
1428
|
+
const layerInput = {
|
|
1429
|
+
id,
|
|
1430
|
+
rect,
|
|
1431
|
+
backdrop: p.backdrop === "none" || p.backdrop === "dim" || p.backdrop === "opaque"
|
|
1432
|
+
? p.backdrop
|
|
1433
|
+
: "dim",
|
|
1434
|
+
modal: true,
|
|
1435
|
+
closeOnEscape: canClose,
|
|
1436
|
+
zIndex,
|
|
1437
|
+
};
|
|
1438
|
+
this.layerRegistry.register(cb ? { ...layerInput, onClose: cb } : layerInput);
|
|
1439
|
+
}
|
|
1440
|
+
break;
|
|
1441
|
+
}
|
|
1442
|
+
case "layer": {
|
|
1443
|
+
const p = v.props;
|
|
1444
|
+
const id = typeof p.id === "string" ? p.id : null;
|
|
1445
|
+
if (id) {
|
|
1446
|
+
const rect = getRectForInstance(cur.instanceId);
|
|
1447
|
+
const baseZ = typeof p.zIndex === "number" && Number.isFinite(p.zIndex)
|
|
1448
|
+
? Math.trunc(p.zIndex)
|
|
1449
|
+
: null;
|
|
1450
|
+
const zIndex = baseZ !== null ? baseZ * 1_000_000 + overlaySeq++ : overlaySeq++;
|
|
1451
|
+
const modal = p.modal === true;
|
|
1452
|
+
const canClose = p.closeOnEscape !== false;
|
|
1453
|
+
this._pooledCloseOnEscape.set(id, canClose);
|
|
1454
|
+
this._pooledCloseOnBackdrop.set(id, false);
|
|
1455
|
+
const cb = typeof p.onClose === "function" ? p.onClose : undefined;
|
|
1456
|
+
if (cb)
|
|
1457
|
+
this._pooledOnClose.set(id, cb);
|
|
1458
|
+
const layerInput = {
|
|
1459
|
+
id,
|
|
1460
|
+
rect,
|
|
1461
|
+
backdrop: p.backdrop === "none" || p.backdrop === "dim" || p.backdrop === "opaque"
|
|
1462
|
+
? p.backdrop
|
|
1463
|
+
: "none",
|
|
1464
|
+
modal,
|
|
1465
|
+
closeOnEscape: canClose,
|
|
1466
|
+
zIndex,
|
|
1467
|
+
};
|
|
1468
|
+
this.layerRegistry.register(cb ? { ...layerInput, onClose: cb } : layerInput);
|
|
1469
|
+
}
|
|
1470
|
+
break;
|
|
1471
|
+
}
|
|
1472
|
+
case "select": {
|
|
1473
|
+
this.selectById.set(v.props.id, v.props);
|
|
1474
|
+
break;
|
|
1475
|
+
}
|
|
1476
|
+
case "checkbox": {
|
|
1477
|
+
this.checkboxById.set(v.props.id, v.props);
|
|
1478
|
+
break;
|
|
1479
|
+
}
|
|
1480
|
+
case "radioGroup": {
|
|
1481
|
+
this.radioGroupById.set(v.props.id, v.props);
|
|
1482
|
+
break;
|
|
1483
|
+
}
|
|
1484
|
+
default:
|
|
1485
|
+
break;
|
|
1486
|
+
}
|
|
1487
|
+
for (let i = cur.children.length - 1; i >= 0; i--) {
|
|
1488
|
+
const c = cur.children[i];
|
|
1489
|
+
if (c)
|
|
1490
|
+
this._pooledRuntimeStack.push(c);
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
this.layerStack = Object.freeze(this.layerRegistry.getAll().map((l) => l.id));
|
|
1494
|
+
this.closeOnEscapeByLayerId = this._pooledCloseOnEscape;
|
|
1495
|
+
this.closeOnBackdropByLayerId = this._pooledCloseOnBackdrop;
|
|
1496
|
+
this.onCloseByLayerId = this._pooledOnClose;
|
|
1497
|
+
this.dropdownStack = Object.freeze(this._pooledDropdownStack.slice());
|
|
1498
|
+
this.toastContainers = Object.freeze(this._pooledToastContainers.slice());
|
|
1499
|
+
// Build toast action maps using pooled collections.
|
|
1500
|
+
this._pooledToastActionByFocusId.clear();
|
|
1501
|
+
this._pooledToastFocusableActionIds.length = 0;
|
|
1502
|
+
for (const tc of this._pooledToastContainers) {
|
|
1503
|
+
if (!tc)
|
|
1504
|
+
continue;
|
|
1505
|
+
const rect = tc.rect;
|
|
1506
|
+
if (rect.w <= 0 || rect.h <= 0)
|
|
1507
|
+
continue;
|
|
1508
|
+
const toasts = tc.props.toasts;
|
|
1509
|
+
const maxVisible = tc.props.maxVisible ?? 5;
|
|
1510
|
+
const maxByHeight = Math.floor(rect.h / TOAST_HEIGHT);
|
|
1511
|
+
const visibleCount = Math.min(toasts.length, maxVisible, maxByHeight);
|
|
1512
|
+
for (let i = 0; i < visibleCount; i++) {
|
|
1513
|
+
const toast = toasts[i];
|
|
1514
|
+
if (!toast?.action)
|
|
1515
|
+
continue;
|
|
1516
|
+
const fid = getToastActionFocusId(toast.id);
|
|
1517
|
+
this._pooledToastActionByFocusId.set(fid, toast.action.onAction);
|
|
1518
|
+
this._pooledToastFocusableActionIds.push(fid);
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
this.toastActionByFocusId = this._pooledToastActionByFocusId;
|
|
1522
|
+
this.toastFocusableActionIds = Object.freeze(this._pooledToastFocusableActionIds.slice());
|
|
1523
|
+
const baseFocusList = this.baseFocusList;
|
|
1524
|
+
const baseEnabledById = this.baseEnabledById;
|
|
1525
|
+
this.focusList = baseFocusList;
|
|
1526
|
+
this.enabledById = baseEnabledById;
|
|
1527
|
+
if (this._pooledToastFocusableActionIds.length > 0) {
|
|
1528
|
+
this.focusList = Object.freeze([...baseFocusList, ...this.toastFocusableActionIds]);
|
|
1529
|
+
const enabled = new Map(baseEnabledById);
|
|
1530
|
+
for (const id of this.toastFocusableActionIds)
|
|
1531
|
+
enabled.set(id, true);
|
|
1532
|
+
this.enabledById = enabled;
|
|
1533
|
+
}
|
|
1534
|
+
const preferredToastFocus = prevFocusedIdBeforeFinalize !== null &&
|
|
1535
|
+
parseToastActionFocusId(prevFocusedIdBeforeFinalize) !== null
|
|
1536
|
+
? prevFocusedIdBeforeFinalize
|
|
1537
|
+
: null;
|
|
1538
|
+
if (preferredToastFocus && this._pooledToastActionByFocusId.has(preferredToastFocus)) {
|
|
1539
|
+
this.focusState = Object.freeze({
|
|
1540
|
+
...this.focusState,
|
|
1541
|
+
focusedId: preferredToastFocus,
|
|
1542
|
+
activeZoneId: null,
|
|
1543
|
+
});
|
|
1544
|
+
}
|
|
1545
|
+
else {
|
|
1546
|
+
const curFocus = this.focusState.focusedId;
|
|
1547
|
+
if (curFocus !== null &&
|
|
1548
|
+
parseToastActionFocusId(curFocus) !== null &&
|
|
1549
|
+
!this._pooledToastActionByFocusId.has(curFocus)) {
|
|
1550
|
+
this.focusState = Object.freeze({
|
|
1551
|
+
...this.focusState,
|
|
1552
|
+
focusedId: null,
|
|
1553
|
+
activeZoneId: null,
|
|
1554
|
+
});
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
rebuildRenderCaches({
|
|
1558
|
+
tableById: this.tableById,
|
|
1559
|
+
logsConsoleById: this.logsConsoleById,
|
|
1560
|
+
diffViewerById: this.diffViewerById,
|
|
1561
|
+
codeEditorById: this.codeEditorById,
|
|
1562
|
+
tableRenderCacheById: this.tableRenderCacheById,
|
|
1563
|
+
logsConsoleRenderCacheById: this.logsConsoleRenderCacheById,
|
|
1564
|
+
diffRenderCacheById: this.diffRenderCacheById,
|
|
1565
|
+
codeEditorRenderCacheById: this.codeEditorRenderCacheById,
|
|
1566
|
+
emptyStringArray: EMPTY_STRING_ARRAY,
|
|
1567
|
+
});
|
|
1568
|
+
if (PERF_DETAIL_ENABLED)
|
|
1569
|
+
perfMarkEnd("routing_rebuild", routingToken);
|
|
1570
|
+
}
|
|
1571
|
+
else if (doLayout && hadRoutingWidgets) {
|
|
1572
|
+
// Layout-only turns (e.g. resize) keep the committed widget maps intact.
|
|
1573
|
+
// Rebuild only rect-dependent overlay/ toast routing state.
|
|
1574
|
+
const routingToken = PERF_DETAIL_ENABLED ? perfMarkStart("routing_rebuild") : 0;
|
|
1575
|
+
const getRectForInstance = (instanceId) => this._pooledRectByInstanceId.get(instanceId) ?? ZERO_RECT;
|
|
1576
|
+
this.layerRegistry.clear();
|
|
1577
|
+
this._pooledCloseOnEscape.clear();
|
|
1578
|
+
this._pooledCloseOnBackdrop.clear();
|
|
1579
|
+
this._pooledOnClose.clear();
|
|
1580
|
+
this._pooledToastContainers.length = 0;
|
|
1581
|
+
let overlaySeq = 0;
|
|
1582
|
+
this._pooledRuntimeStack.length = 0;
|
|
1583
|
+
this._pooledRuntimeStack.push(this.committedRoot);
|
|
1584
|
+
while (this._pooledRuntimeStack.length > 0) {
|
|
1585
|
+
const cur = this._pooledRuntimeStack.pop();
|
|
1586
|
+
if (!cur)
|
|
1587
|
+
continue;
|
|
1588
|
+
const v = cur.vnode;
|
|
1589
|
+
switch (v.kind) {
|
|
1590
|
+
case "toastContainer": {
|
|
1591
|
+
const p = v.props;
|
|
1592
|
+
const rect = getRectForInstance(cur.instanceId);
|
|
1593
|
+
this._pooledToastContainers.push({ rect, props: p });
|
|
1594
|
+
break;
|
|
1595
|
+
}
|
|
1596
|
+
case "modal": {
|
|
1597
|
+
const p = v.props;
|
|
1598
|
+
const id = typeof p.id === "string" ? p.id : null;
|
|
1599
|
+
if (id) {
|
|
1600
|
+
const rect = getRectForInstance(cur.instanceId);
|
|
1601
|
+
const zIndex = overlaySeq++;
|
|
1602
|
+
const canClose = p.closeOnEscape !== false;
|
|
1603
|
+
this._pooledCloseOnEscape.set(id, canClose);
|
|
1604
|
+
this._pooledCloseOnBackdrop.set(id, p.closeOnBackdrop !== false);
|
|
1605
|
+
const cb = typeof p.onClose === "function" ? p.onClose : undefined;
|
|
1606
|
+
if (cb)
|
|
1607
|
+
this._pooledOnClose.set(id, cb);
|
|
1608
|
+
const layerInput = {
|
|
1609
|
+
id,
|
|
1610
|
+
rect,
|
|
1611
|
+
backdrop: p.backdrop === "none" || p.backdrop === "dim" || p.backdrop === "opaque"
|
|
1612
|
+
? p.backdrop
|
|
1613
|
+
: "dim",
|
|
1614
|
+
modal: true,
|
|
1615
|
+
closeOnEscape: canClose,
|
|
1616
|
+
zIndex,
|
|
1617
|
+
};
|
|
1618
|
+
this.layerRegistry.register(cb ? { ...layerInput, onClose: cb } : layerInput);
|
|
1619
|
+
}
|
|
1620
|
+
break;
|
|
1621
|
+
}
|
|
1622
|
+
case "layer": {
|
|
1623
|
+
const p = v.props;
|
|
1624
|
+
const id = typeof p.id === "string" ? p.id : null;
|
|
1625
|
+
if (id) {
|
|
1626
|
+
const rect = getRectForInstance(cur.instanceId);
|
|
1627
|
+
const baseZ = typeof p.zIndex === "number" && Number.isFinite(p.zIndex)
|
|
1628
|
+
? Math.trunc(p.zIndex)
|
|
1629
|
+
: null;
|
|
1630
|
+
const zIndex = baseZ !== null ? baseZ * 1_000_000 + overlaySeq++ : overlaySeq++;
|
|
1631
|
+
const modal = p.modal === true;
|
|
1632
|
+
const canClose = p.closeOnEscape !== false;
|
|
1633
|
+
this._pooledCloseOnEscape.set(id, canClose);
|
|
1634
|
+
this._pooledCloseOnBackdrop.set(id, false);
|
|
1635
|
+
const cb = typeof p.onClose === "function" ? p.onClose : undefined;
|
|
1636
|
+
if (cb)
|
|
1637
|
+
this._pooledOnClose.set(id, cb);
|
|
1638
|
+
const layerInput = {
|
|
1639
|
+
id,
|
|
1640
|
+
rect,
|
|
1641
|
+
backdrop: p.backdrop === "none" || p.backdrop === "dim" || p.backdrop === "opaque"
|
|
1642
|
+
? p.backdrop
|
|
1643
|
+
: "none",
|
|
1644
|
+
modal,
|
|
1645
|
+
closeOnEscape: canClose,
|
|
1646
|
+
zIndex,
|
|
1647
|
+
};
|
|
1648
|
+
this.layerRegistry.register(cb ? { ...layerInput, onClose: cb } : layerInput);
|
|
1649
|
+
}
|
|
1650
|
+
break;
|
|
1651
|
+
}
|
|
1652
|
+
default:
|
|
1653
|
+
break;
|
|
1654
|
+
}
|
|
1655
|
+
for (let i = cur.children.length - 1; i >= 0; i--) {
|
|
1656
|
+
const c = cur.children[i];
|
|
1657
|
+
if (c)
|
|
1658
|
+
this._pooledRuntimeStack.push(c);
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
this.layerStack = Object.freeze(this.layerRegistry.getAll().map((l) => l.id));
|
|
1662
|
+
this.closeOnEscapeByLayerId = this._pooledCloseOnEscape;
|
|
1663
|
+
this.closeOnBackdropByLayerId = this._pooledCloseOnBackdrop;
|
|
1664
|
+
this.onCloseByLayerId = this._pooledOnClose;
|
|
1665
|
+
this.toastContainers = Object.freeze(this._pooledToastContainers.slice());
|
|
1666
|
+
this._pooledToastActionByFocusId.clear();
|
|
1667
|
+
this._pooledToastFocusableActionIds.length = 0;
|
|
1668
|
+
for (const tc of this._pooledToastContainers) {
|
|
1669
|
+
if (!tc)
|
|
1670
|
+
continue;
|
|
1671
|
+
const rect = tc.rect;
|
|
1672
|
+
if (rect.w <= 0 || rect.h <= 0)
|
|
1673
|
+
continue;
|
|
1674
|
+
const toasts = tc.props.toasts;
|
|
1675
|
+
const maxVisible = tc.props.maxVisible ?? 5;
|
|
1676
|
+
const maxByHeight = Math.floor(rect.h / TOAST_HEIGHT);
|
|
1677
|
+
const visibleCount = Math.min(toasts.length, maxVisible, maxByHeight);
|
|
1678
|
+
for (let i = 0; i < visibleCount; i++) {
|
|
1679
|
+
const toast = toasts[i];
|
|
1680
|
+
if (!toast?.action)
|
|
1681
|
+
continue;
|
|
1682
|
+
const fid = getToastActionFocusId(toast.id);
|
|
1683
|
+
this._pooledToastActionByFocusId.set(fid, toast.action.onAction);
|
|
1684
|
+
this._pooledToastFocusableActionIds.push(fid);
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
this.toastActionByFocusId = this._pooledToastActionByFocusId;
|
|
1688
|
+
this.toastFocusableActionIds = Object.freeze(this._pooledToastFocusableActionIds.slice());
|
|
1689
|
+
const baseFocusList = this.baseFocusList;
|
|
1690
|
+
const baseEnabledById = this.baseEnabledById;
|
|
1691
|
+
this.focusList = baseFocusList;
|
|
1692
|
+
this.enabledById = baseEnabledById;
|
|
1693
|
+
if (this._pooledToastFocusableActionIds.length > 0) {
|
|
1694
|
+
this.focusList = Object.freeze([...baseFocusList, ...this.toastFocusableActionIds]);
|
|
1695
|
+
const enabled = new Map(baseEnabledById);
|
|
1696
|
+
for (const id of this.toastFocusableActionIds)
|
|
1697
|
+
enabled.set(id, true);
|
|
1698
|
+
this.enabledById = enabled;
|
|
1699
|
+
}
|
|
1700
|
+
const curFocus = this.focusState.focusedId;
|
|
1701
|
+
if (curFocus !== null &&
|
|
1702
|
+
parseToastActionFocusId(curFocus) !== null &&
|
|
1703
|
+
!this._pooledToastActionByFocusId.has(curFocus)) {
|
|
1704
|
+
this.focusState = Object.freeze({
|
|
1705
|
+
...this.focusState,
|
|
1706
|
+
focusedId: null,
|
|
1707
|
+
activeZoneId: null,
|
|
1708
|
+
});
|
|
1709
|
+
}
|
|
1710
|
+
if (PERF_DETAIL_ENABLED)
|
|
1711
|
+
perfMarkEnd("routing_rebuild", routingToken);
|
|
1712
|
+
}
|
|
1713
|
+
if (doCommit && !didRoutingRebuild) {
|
|
1714
|
+
this.hadRoutingWidgets = hasRoutingWidgets;
|
|
1715
|
+
}
|
|
1716
|
+
if (doCommit && didRoutingRebuild) {
|
|
1717
|
+
// Precompute flattened file trees for filePicker/fileTreeExplorer to avoid per-frame allocations.
|
|
1718
|
+
for (const fp of this.filePickerById.values()) {
|
|
1719
|
+
const s = this.treeStore.get(fp.id);
|
|
1720
|
+
if (!readFileNodeFlatCache(s, fp.data, fp.expandedPaths)) {
|
|
1721
|
+
const next = flattenTree(fp.data, fileNodeGetKey, fileNodeGetChildren, fileNodeHasChildren, fp.expandedPaths);
|
|
1722
|
+
this.treeStore.set(fp.id, {
|
|
1723
|
+
flatCache: makeFileNodeFlatCache(fp.data, fp.expandedPaths, next),
|
|
1724
|
+
});
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
for (const fte of this.fileTreeExplorerById.values()) {
|
|
1728
|
+
const s = this.treeStore.get(fte.id);
|
|
1729
|
+
if (!readFileNodeFlatCache(s, fte.data, fte.expanded)) {
|
|
1730
|
+
const next = flattenTree(fte.data, fileNodeGetKey, fileNodeGetChildren, fileNodeHasChildren, fte.expanded);
|
|
1731
|
+
this.treeStore.set(fte.id, {
|
|
1732
|
+
flatCache: makeFileNodeFlatCache(fte.data, fte.expanded, next),
|
|
1733
|
+
});
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
// Garbage collect per-dropdown routing state for dropdowns that were removed.
|
|
1737
|
+
for (const prevDropdownId of this._pooledPrevDropdownIds) {
|
|
1738
|
+
if (!this.dropdownById.has(prevDropdownId)) {
|
|
1739
|
+
this.dropdownSelectedIndexById.delete(prevDropdownId);
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
// Garbage collect per-tree lazy-loading caches for trees that were removed.
|
|
1743
|
+
for (const prevTreeId of this._pooledPrevTreeIds) {
|
|
1744
|
+
if (!this.treeById.has(prevTreeId)) {
|
|
1745
|
+
this.loadedTreeChildrenByTreeId.delete(prevTreeId);
|
|
1746
|
+
const prefix = `${prevTreeId}\u0000`;
|
|
1747
|
+
for (const tokenKey of this.treeLoadTokenByTreeAndKey.keys()) {
|
|
1748
|
+
if (tokenKey.startsWith(prefix))
|
|
1749
|
+
this.treeLoadTokenByTreeAndKey.delete(tokenKey);
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
// Garbage collect treeStore entries for tree-like widgets that were removed.
|
|
1754
|
+
for (const prevId of this._pooledPrevTreeStoreIds) {
|
|
1755
|
+
if (!this.treeById.has(prevId) &&
|
|
1756
|
+
!this.filePickerById.has(prevId) &&
|
|
1757
|
+
!this.fileTreeExplorerById.has(prevId)) {
|
|
1758
|
+
this.treeStore.delete(prevId);
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
// Garbage collect command palette async state for palettes that were removed.
|
|
1762
|
+
for (const prevId of this._pooledPrevCommandPaletteIds) {
|
|
1763
|
+
if (!this.commandPaletteById.has(prevId)) {
|
|
1764
|
+
this.commandPaletteItemsById.delete(prevId);
|
|
1765
|
+
this.commandPaletteLoadingById.delete(prevId);
|
|
1766
|
+
this.commandPaletteFetchTokenById.delete(prevId);
|
|
1767
|
+
this.commandPaletteLastQueryById.delete(prevId);
|
|
1768
|
+
this.commandPaletteLastSourcesRefById.delete(prevId);
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
for (const prevId of this._pooledPrevToolApprovalDialogIds) {
|
|
1772
|
+
if (!this.toolApprovalDialogById.has(prevId)) {
|
|
1773
|
+
this.toolApprovalFocusedActionById.delete(prevId);
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
for (const prevId of this._pooledPrevDiffViewerIds) {
|
|
1777
|
+
if (!this.diffViewerById.has(prevId)) {
|
|
1778
|
+
this.diffViewerFocusedHunkById.delete(prevId);
|
|
1779
|
+
this.diffViewerExpandedHunksById.delete(prevId);
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
for (const prevId of this._pooledPrevLogsConsoleIds) {
|
|
1783
|
+
if (!this.logsConsoleById.has(prevId)) {
|
|
1784
|
+
this.logsConsoleLastGTimeById.delete(prevId);
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
if (doCommit) {
|
|
1789
|
+
// Reset per-commit working values to the committed props.value, and normalize cursor (docs/18).
|
|
1790
|
+
for (const meta of this.inputById.values()) {
|
|
1791
|
+
const instanceId = meta.instanceId;
|
|
1792
|
+
this.inputWorkingValueByInstanceId.set(instanceId, meta.value);
|
|
1793
|
+
const prev = this.inputCursorByInstanceId.get(instanceId);
|
|
1794
|
+
const init = prev === undefined ? meta.value.length : prev;
|
|
1795
|
+
this.inputCursorByInstanceId.set(instanceId, normalizeInputCursor(meta.value, init));
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
if ((doCommit || doLayout) && this.pressedId !== null) {
|
|
1799
|
+
if (this.enabledById.get(this.pressedId) !== true) {
|
|
1800
|
+
this.pressedId = null;
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
// Build cursor info for v2 protocol
|
|
1804
|
+
const cursorInfo = this.useV2Cursor
|
|
1805
|
+
? {
|
|
1806
|
+
cursorByInstanceId: this.inputCursorByInstanceId,
|
|
1807
|
+
shape: this.cursorShape,
|
|
1808
|
+
blink: this.cursorBlink,
|
|
1809
|
+
}
|
|
1810
|
+
: undefined;
|
|
1811
|
+
if (doCommit) {
|
|
1812
|
+
kickoffCommandPaletteItemFetches(this.commandPaletteById, this.commandPaletteItemsById, this.commandPaletteLoadingById, this.commandPaletteFetchTokenById, this.commandPaletteLastQueryById, this.commandPaletteLastSourcesRefById, this.requestRender);
|
|
1813
|
+
}
|
|
1814
|
+
const renderToken = perfMarkStart("render");
|
|
1815
|
+
renderToDrawlist({
|
|
1816
|
+
tree: this.committedRoot,
|
|
1817
|
+
layout: this.layoutTree,
|
|
1818
|
+
viewport,
|
|
1819
|
+
focusState: this.focusState,
|
|
1820
|
+
builder: this.builder,
|
|
1821
|
+
theme,
|
|
1822
|
+
cursorInfo,
|
|
1823
|
+
virtualListStore: this.virtualListStore,
|
|
1824
|
+
tableStore: this.tableStore,
|
|
1825
|
+
treeStore: this.treeStore,
|
|
1826
|
+
loadedTreeChildrenById: this.loadedTreeChildrenByTreeId,
|
|
1827
|
+
commandPaletteItemsById: this.commandPaletteItemsById,
|
|
1828
|
+
commandPaletteLoadingById: this.commandPaletteLoadingById,
|
|
1829
|
+
toolApprovalFocusedActionById: this.toolApprovalFocusedActionById,
|
|
1830
|
+
diffViewerFocusedHunkById: this.diffViewerFocusedHunkById,
|
|
1831
|
+
diffViewerExpandedHunksById: this.diffViewerExpandedHunksById,
|
|
1832
|
+
layoutIndex: this._pooledRectByInstanceId,
|
|
1833
|
+
idRectIndex: this._pooledRectById,
|
|
1834
|
+
tableRenderCacheById: this.tableRenderCacheById,
|
|
1835
|
+
logsConsoleRenderCacheById: this.logsConsoleRenderCacheById,
|
|
1836
|
+
diffRenderCacheById: this.diffRenderCacheById,
|
|
1837
|
+
codeEditorRenderCacheById: this.codeEditorRenderCacheById,
|
|
1838
|
+
});
|
|
1839
|
+
perfMarkEnd("render", renderToken);
|
|
1840
|
+
const buildToken = perfMarkStart("drawlist_build");
|
|
1841
|
+
const built = this.builder.build();
|
|
1842
|
+
perfMarkEnd("drawlist_build", buildToken);
|
|
1843
|
+
if (!built.ok) {
|
|
1844
|
+
return {
|
|
1845
|
+
ok: false,
|
|
1846
|
+
code: "ZRUI_DRAWLIST_BUILD_ERROR",
|
|
1847
|
+
detail: `${built.error.code}: ${built.error.detail}`,
|
|
1848
|
+
};
|
|
1849
|
+
}
|
|
1850
|
+
// Render hooks are for preventing re-entrant app API calls during user render.
|
|
1851
|
+
hooks.exitRender();
|
|
1852
|
+
entered = false;
|
|
1853
|
+
// Run composite effects after a successful commit+render build.
|
|
1854
|
+
if (commitRes) {
|
|
1855
|
+
const effectsToken = PERF_DETAIL_ENABLED ? perfMarkStart("effects") : 0;
|
|
1856
|
+
try {
|
|
1857
|
+
runPendingEffects(commitRes.pendingEffects);
|
|
1858
|
+
}
|
|
1859
|
+
catch (e) {
|
|
1860
|
+
return { ok: false, code: "ZRUI_USER_CODE_THROW", detail: describeThrown(e) };
|
|
1861
|
+
}
|
|
1862
|
+
finally {
|
|
1863
|
+
if (PERF_DETAIL_ENABLED)
|
|
1864
|
+
perfMarkEnd("effects", effectsToken);
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
try {
|
|
1868
|
+
const backendToken = PERF_ENABLED ? perfMarkStart("backend_request") : 0;
|
|
1869
|
+
try {
|
|
1870
|
+
const inFlight = this.backend.requestFrame(built.bytes);
|
|
1871
|
+
return { ok: true, inFlight };
|
|
1872
|
+
}
|
|
1873
|
+
finally {
|
|
1874
|
+
if (PERF_ENABLED)
|
|
1875
|
+
perfMarkEnd("backend_request", backendToken);
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
catch (e) {
|
|
1879
|
+
return { ok: false, code: "ZRUI_BACKEND_ERROR", detail: describeThrown(e) };
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
catch (e) {
|
|
1883
|
+
return { ok: false, code: "ZRUI_USER_CODE_THROW", detail: describeThrown(e) };
|
|
1884
|
+
}
|
|
1885
|
+
finally {
|
|
1886
|
+
if (entered)
|
|
1887
|
+
hooks.exitRender();
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
//# sourceMappingURL=widgetRenderer.js.map
|