react-native-gtkx 0.2.0-alpha.1 → 0.3.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 +14 -2
- package/dist/adw/widgets.generated.d.ts +4 -4
- package/dist/adw/widgets.generated.js +51 -51
- package/dist/adw/widgets.generated.js.map +1 -1
- package/dist/aliases/index.d.ts +84 -0
- package/dist/aliases/index.js +208 -0
- package/dist/aliases/index.js.map +1 -0
- package/dist/animated/create-animated.d.ts +2 -0
- package/dist/animated/create-animated.js +2 -0
- package/dist/animated/create-animated.js.map +1 -1
- package/dist/animated/index.d.ts +4 -0
- package/dist/animated/index.js +6 -0
- package/dist/animated/index.js.map +1 -1
- package/dist/animated/types.d.ts +1 -0
- package/dist/animated/types.js.map +1 -1
- package/dist/animated/value-animation.js +17 -4
- package/dist/animated/value-animation.js.map +1 -1
- package/dist/animated/value-xy.d.ts +41 -0
- package/dist/animated/value-xy.js +90 -0
- package/dist/animated/value-xy.js.map +1 -0
- package/dist/animated/value.d.ts +9 -0
- package/dist/animated/value.js +30 -2
- package/dist/animated/value.js.map +1 -1
- package/dist/apis/host.gtkx.js +9 -12
- package/dist/apis/host.gtkx.js.map +1 -1
- package/dist/apis/index.d.ts +4 -2
- package/dist/apis/index.js +2 -0
- package/dist/apis/index.js.map +1 -1
- package/dist/apis/keyboard.d.ts +60 -0
- package/dist/apis/keyboard.js +63 -0
- package/dist/apis/keyboard.js.map +1 -0
- package/dist/apis/log-box.d.ts +15 -0
- package/dist/apis/log-box.js +46 -0
- package/dist/apis/log-box.js.map +1 -0
- package/dist/apis/platform.d.ts +18 -1
- package/dist/apis/platform.js.map +1 -1
- package/dist/common/icon.d.ts +23 -0
- package/dist/common/icon.js +14 -0
- package/dist/common/icon.js.map +1 -0
- package/dist/common/index.d.ts +1 -0
- package/dist/common/index.js +25 -0
- package/dist/common/index.js.map +1 -1
- package/dist/common/widget.d.ts +1 -22
- package/dist/common/widget.js +75 -8
- package/dist/common/widget.js.map +1 -1
- package/dist/components/animated.d.ts +73 -7
- package/dist/components/animated.js +560 -45
- package/dist/components/animated.js.map +1 -1
- package/dist/components/app-registry.d.ts +26 -0
- package/dist/components/app-registry.js.map +1 -1
- package/dist/components/driven-size.d.ts +27 -0
- package/dist/components/driven-size.js +85 -0
- package/dist/components/driven-size.js.map +1 -0
- package/dist/components/find-node-handle.d.ts +11 -0
- package/dist/components/find-node-handle.js +53 -0
- package/dist/components/find-node-handle.js.map +1 -0
- package/dist/components/flat-list.d.ts +3 -2
- package/dist/components/flat-list.js.map +1 -1
- package/dist/components/frame-scheduler.d.ts +16 -0
- package/dist/components/frame-scheduler.js +37 -0
- package/dist/components/frame-scheduler.js.map +1 -0
- package/dist/components/host-node.d.ts +7 -0
- package/dist/components/host-node.js +26 -1
- package/dist/components/host-node.js.map +1 -1
- package/dist/components/image.d.ts +6 -1
- package/dist/components/image.js +15 -4
- package/dist/components/image.js.map +1 -1
- package/dist/components/index.d.ts +11 -5
- package/dist/components/index.js +7 -4
- package/dist/components/index.js.map +1 -1
- package/dist/components/measure.d.ts +63 -0
- package/dist/components/measure.js +150 -0
- package/dist/components/measure.js.map +1 -0
- package/dist/components/modal.d.ts +1 -1
- package/dist/components/press-event.d.ts +28 -0
- package/dist/components/press-event.js +46 -0
- package/dist/components/press-event.js.map +1 -0
- package/dist/components/pressable.d.ts +63 -7
- package/dist/components/pressable.js +165 -12
- package/dist/components/pressable.js.map +1 -1
- package/dist/components/rect-store.d.ts +58 -0
- package/dist/components/rect-store.js +124 -3
- package/dist/components/rect-store.js.map +1 -1
- package/dist/components/root.js +6 -1
- package/dist/components/root.js.map +1 -1
- package/dist/components/scroll-phase.d.ts +35 -0
- package/dist/components/scroll-phase.js +26 -0
- package/dist/components/scroll-phase.js.map +1 -0
- package/dist/components/scroll-view.d.ts +43 -3
- package/dist/components/scroll-view.js +386 -45
- package/dist/components/scroll-view.js.map +1 -1
- package/dist/components/text-input.js +9 -25
- package/dist/components/text-input.js.map +1 -1
- package/dist/components/text.d.ts +6 -2
- package/dist/components/text.js +68 -9
- package/dist/components/text.js.map +1 -1
- package/dist/components/use-focus.d.ts +27 -0
- package/dist/components/use-focus.js +116 -0
- package/dist/components/use-focus.js.map +1 -0
- package/dist/components/use-layout-child.d.ts +13 -1
- package/dist/components/use-layout-child.js +205 -19
- package/dist/components/use-layout-child.js.map +1 -1
- package/dist/components/view.d.ts +12 -4
- package/dist/components/view.js +25 -14
- package/dist/components/view.js.map +1 -1
- package/dist/components/virtualized-list.d.ts +45 -5
- package/dist/components/virtualized-list.js +90 -24
- package/dist/components/virtualized-list.js.map +1 -1
- package/dist/components/wheel-scroll-session.d.ts +7 -0
- package/dist/components/wheel-scroll-session.js +53 -0
- package/dist/components/wheel-scroll-session.js.map +1 -0
- package/dist/components/widget-retention.d.ts +35 -0
- package/dist/components/widget-retention.js +169 -0
- package/dist/components/widget-retention.js.map +1 -0
- package/dist/contracts.d.ts +23 -3
- package/dist/contracts.js.map +1 -1
- package/dist/dnd/context.d.ts +69 -0
- package/dist/dnd/context.js +149 -0
- package/dist/dnd/context.js.map +1 -0
- package/dist/dnd/draggable.d.ts +59 -0
- package/dist/dnd/draggable.js +149 -0
- package/dist/dnd/draggable.js.map +1 -0
- package/dist/dnd/droppable.d.ts +24 -0
- package/dist/dnd/droppable.js +74 -0
- package/dist/dnd/droppable.js.map +1 -0
- package/dist/dnd/gtk-controllers.d.ts +39 -0
- package/dist/dnd/gtk-controllers.js +110 -0
- package/dist/dnd/gtk-controllers.js.map +1 -0
- package/dist/dnd/index.d.ts +6 -0
- package/dist/dnd/index.js +31 -0
- package/dist/dnd/index.js.map +1 -0
- package/dist/dnd/order.d.ts +7 -0
- package/dist/dnd/order.js +20 -0
- package/dist/dnd/order.js.map +1 -0
- package/dist/dnd/payload.d.ts +14 -0
- package/dist/dnd/payload.js +41 -0
- package/dist/dnd/payload.js.map +1 -0
- package/dist/dnd/sortable.d.ts +49 -0
- package/dist/dnd/sortable.js +307 -0
- package/dist/dnd/sortable.js.map +1 -0
- package/dist/dnd/types.d.ts +290 -0
- package/dist/dnd/types.js +25 -0
- package/dist/dnd/types.js.map +1 -0
- package/dist/gesture-handler-compat/builder.d.ts +251 -0
- package/dist/gesture-handler-compat/builder.js +513 -0
- package/dist/gesture-handler-compat/builder.js.map +1 -0
- package/dist/gesture-handler-compat/composition.d.ts +23 -0
- package/dist/gesture-handler-compat/composition.js +111 -0
- package/dist/gesture-handler-compat/composition.js.map +1 -0
- package/dist/gesture-handler-compat/deciders.d.ts +3 -0
- package/dist/gesture-handler-compat/deciders.js +47 -0
- package/dist/gesture-handler-compat/deciders.js.map +1 -0
- package/dist/gesture-handler-compat/detector-runtime.d.ts +44 -0
- package/dist/gesture-handler-compat/detector-runtime.js +374 -0
- package/dist/gesture-handler-compat/detector-runtime.js.map +1 -0
- package/dist/gesture-handler-compat/detector.d.ts +22 -0
- package/dist/gesture-handler-compat/detector.js +104 -0
- package/dist/gesture-handler-compat/detector.js.map +1 -0
- package/dist/gesture-handler-compat/fling.d.ts +24 -0
- package/dist/gesture-handler-compat/fling.js +123 -0
- package/dist/gesture-handler-compat/fling.js.map +1 -0
- package/dist/gesture-handler-compat/force-touch.d.ts +13 -0
- package/dist/gesture-handler-compat/force-touch.js +40 -0
- package/dist/gesture-handler-compat/force-touch.js.map +1 -0
- package/dist/gesture-handler-compat/hooks.d.ts +157 -0
- package/dist/gesture-handler-compat/hooks.js +268 -0
- package/dist/gesture-handler-compat/hooks.js.map +1 -0
- package/dist/gesture-handler-compat/hover.d.ts +2 -0
- package/dist/gesture-handler-compat/hover.js +22 -0
- package/dist/gesture-handler-compat/hover.js.map +1 -0
- package/dist/gesture-handler-compat/index.d.ts +98 -0
- package/dist/gesture-handler-compat/index.js +255 -0
- package/dist/gesture-handler-compat/index.js.map +1 -0
- package/dist/gesture-handler-compat/long-press.d.ts +6 -0
- package/dist/gesture-handler-compat/long-press.js +21 -0
- package/dist/gesture-handler-compat/long-press.js.map +1 -0
- package/dist/gesture-handler-compat/manual.d.ts +2 -0
- package/dist/gesture-handler-compat/manual.js +18 -0
- package/dist/gesture-handler-compat/manual.js.map +1 -0
- package/dist/gesture-handler-compat/native.d.ts +7 -0
- package/dist/gesture-handler-compat/native.js +34 -0
- package/dist/gesture-handler-compat/native.js.map +1 -0
- package/dist/gesture-handler-compat/orchestrator.d.ts +77 -0
- package/dist/gesture-handler-compat/orchestrator.js +284 -0
- package/dist/gesture-handler-compat/orchestrator.js.map +1 -0
- package/dist/gesture-handler-compat/pan.d.ts +23 -0
- package/dist/gesture-handler-compat/pan.js +116 -0
- package/dist/gesture-handler-compat/pan.js.map +1 -0
- package/dist/gesture-handler-compat/recognizer.d.ts +268 -0
- package/dist/gesture-handler-compat/recognizer.js +1056 -0
- package/dist/gesture-handler-compat/recognizer.js.map +1 -0
- package/dist/gesture-handler-compat/relations.d.ts +43 -0
- package/dist/gesture-handler-compat/relations.js +128 -0
- package/dist/gesture-handler-compat/relations.js.map +1 -0
- package/dist/gesture-handler-compat/tap.d.ts +6 -0
- package/dist/gesture-handler-compat/tap.js +29 -0
- package/dist/gesture-handler-compat/tap.js.map +1 -0
- package/dist/gesture-handler-compat/touchpad.d.ts +41 -0
- package/dist/gesture-handler-compat/touchpad.js +64 -0
- package/dist/gesture-handler-compat/touchpad.js.map +1 -0
- package/dist/gesture-handler-compat/types.d.ts +441 -0
- package/dist/gesture-handler-compat/types.js +167 -0
- package/dist/gesture-handler-compat/types.js.map +1 -0
- package/dist/gtk/controllers.d.ts +39 -0
- package/dist/gtk/controllers.js +92 -0
- package/dist/gtk/controllers.js.map +1 -0
- package/dist/gtk/index.d.ts +3 -1
- package/dist/gtk/index.js +14 -1
- package/dist/gtk/index.js.map +1 -1
- package/dist/gtk/widgets.generated.d.ts +14 -14
- package/dist/gtk/widgets.generated.js +101 -102
- package/dist/gtk/widgets.generated.js.map +1 -1
- package/dist/gtk/window-actions.d.ts +77 -0
- package/dist/gtk/window-actions.js +193 -0
- package/dist/gtk/window-actions.js.map +1 -0
- package/dist/gtkx/bridge/geometry.d.ts +15 -0
- package/dist/gtkx/bridge/geometry.js +40 -0
- package/dist/gtkx/bridge/geometry.js.map +1 -0
- package/dist/gtkx/bridge/index.d.ts +7 -3
- package/dist/gtkx/bridge/index.js +12 -4
- package/dist/gtkx/bridge/index.js.map +1 -1
- package/dist/gtkx/bridge/slot-portal.d.ts +12 -0
- package/dist/gtkx/bridge/slot-portal.js +17 -0
- package/dist/gtkx/bridge/slot-portal.js.map +1 -0
- package/dist/gtkx/bridge/svg-node.js +10 -54
- package/dist/gtkx/bridge/svg-node.js.map +1 -1
- package/dist/gtkx/bridge/use-signal.js +2 -2
- package/dist/gtkx/bridge/use-signal.js.map +1 -1
- package/dist/gtkx/bridge/view-box.d.ts +56 -0
- package/dist/gtkx/bridge/view-box.js +394 -9
- package/dist/gtkx/bridge/view-box.js.map +1 -1
- package/dist/gtkx/bridge/widget-css.d.ts +17 -0
- package/dist/gtkx/bridge/widget-css.js +72 -0
- package/dist/gtkx/bridge/widget-css.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/layout/driven-size.d.ts +12 -0
- package/dist/layout/driven-size.js +70 -0
- package/dist/layout/driven-size.js.map +1 -0
- package/dist/layout/engine.d.ts +17 -1
- package/dist/layout/engine.js +3 -20
- package/dist/layout/engine.js.map +1 -1
- package/dist/layout/node.d.ts +13 -0
- package/dist/layout/node.js +14 -0
- package/dist/layout/node.js.map +1 -1
- package/dist/layout/yoga.d.ts +3 -2
- package/dist/layout/yoga.js +5 -2
- package/dist/layout/yoga.js.map +1 -1
- package/dist/mcp/data/generated.d.ts +310 -91
- package/dist/mcp/data/generated.js +365 -90
- package/dist/mcp/data/generated.js.map +1 -1
- package/dist/mcp/server.js +1 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/metro/index.d.ts +10 -0
- package/dist/metro/index.js +21 -12
- package/dist/metro/index.js.map +1 -1
- package/dist/navigation/sidebar.d.ts +47 -1
- package/dist/navigation/sidebar.js +77 -3
- package/dist/navigation/sidebar.js.map +1 -1
- package/dist/reanimated-compat/animated-ref.d.ts +32 -0
- package/dist/reanimated-compat/animated-ref.js +57 -0
- package/dist/reanimated-compat/animated-ref.js.map +1 -0
- package/dist/reanimated-compat/animation.d.ts +177 -0
- package/dist/reanimated-compat/animation.js +540 -0
- package/dist/reanimated-compat/animation.js.map +1 -0
- package/dist/reanimated-compat/color.d.ts +28 -0
- package/dist/reanimated-compat/color.js +249 -0
- package/dist/reanimated-compat/color.js.map +1 -0
- package/dist/reanimated-compat/decay.d.ts +39 -0
- package/dist/reanimated-compat/decay.js +96 -0
- package/dist/reanimated-compat/decay.js.map +1 -0
- package/dist/reanimated-compat/easing.d.ts +30 -0
- package/dist/reanimated-compat/easing.js +76 -0
- package/dist/reanimated-compat/easing.js.map +1 -0
- package/dist/reanimated-compat/hooks.d.ts +14 -0
- package/dist/reanimated-compat/hooks.js +217 -0
- package/dist/reanimated-compat/hooks.js.map +1 -0
- package/dist/reanimated-compat/index.d.ts +258 -0
- package/dist/reanimated-compat/index.js +464 -0
- package/dist/reanimated-compat/index.js.map +1 -0
- package/dist/reanimated-compat/interpolation.d.ts +18 -0
- package/dist/reanimated-compat/interpolation.js +122 -0
- package/dist/reanimated-compat/interpolation.js.map +1 -0
- package/dist/reanimated-compat/layout-animation-config.d.ts +43 -0
- package/dist/reanimated-compat/layout-animation-config.js +78 -0
- package/dist/reanimated-compat/layout-animation-config.js.map +1 -0
- package/dist/reanimated-compat/layout-animation-presets.d.ts +117 -0
- package/dist/reanimated-compat/layout-animation-presets.js +498 -0
- package/dist/reanimated-compat/layout-animation-presets.js.map +1 -0
- package/dist/reanimated-compat/layout-animation-runtime.d.ts +21 -0
- package/dist/reanimated-compat/layout-animation-runtime.js +311 -0
- package/dist/reanimated-compat/layout-animation-runtime.js.map +1 -0
- package/dist/reanimated-compat/layout-animation-view.d.ts +27 -0
- package/dist/reanimated-compat/layout-animation-view.js +266 -0
- package/dist/reanimated-compat/layout-animation-view.js.map +1 -0
- package/dist/reanimated-compat/layout-animation.d.ts +171 -0
- package/dist/reanimated-compat/layout-animation.js +469 -0
- package/dist/reanimated-compat/layout-animation.js.map +1 -0
- package/dist/reanimated-compat/layout-transitions.d.ts +83 -0
- package/dist/reanimated-compat/layout-transitions.js +350 -0
- package/dist/reanimated-compat/layout-transitions.js.map +1 -0
- package/dist/reanimated-compat/mutable.d.ts +29 -0
- package/dist/reanimated-compat/mutable.js +139 -0
- package/dist/reanimated-compat/mutable.js.map +1 -0
- package/dist/reanimated-compat/props.d.ts +18 -0
- package/dist/reanimated-compat/props.js +111 -0
- package/dist/reanimated-compat/props.js.map +1 -0
- package/dist/reanimated-compat/scroll-handler.d.ts +119 -0
- package/dist/reanimated-compat/scroll-handler.js +274 -0
- package/dist/reanimated-compat/scroll-handler.js.map +1 -0
- package/dist/reanimated-compat/scroll-offset.d.ts +12 -0
- package/dist/reanimated-compat/scroll-offset.js +104 -0
- package/dist/reanimated-compat/scroll-offset.js.map +1 -0
- package/dist/reanimated-compat/style.d.ts +90 -0
- package/dist/reanimated-compat/style.js +452 -0
- package/dist/reanimated-compat/style.js.map +1 -0
- package/dist/reanimated-compat/test-timers.d.ts +28 -0
- package/dist/reanimated-compat/test-timers.js +136 -0
- package/dist/reanimated-compat/test-timers.js.map +1 -0
- package/dist/reanimated-compat/threads.d.ts +13 -0
- package/dist/reanimated-compat/threads.js +41 -0
- package/dist/reanimated-compat/threads.js.map +1 -0
- package/dist/reanimated-compat/tracking.d.ts +41 -0
- package/dist/reanimated-compat/tracking.js +106 -0
- package/dist/reanimated-compat/tracking.js.map +1 -0
- package/dist/reanimated-compat/updater-animations.d.ts +36 -0
- package/dist/reanimated-compat/updater-animations.js +273 -0
- package/dist/reanimated-compat/updater-animations.js.map +1 -0
- package/dist/responder/system.d.ts +100 -0
- package/dist/responder/system.js +304 -0
- package/dist/responder/system.js.map +1 -0
- package/dist/responder/touch-history.d.ts +10 -0
- package/dist/responder/touch-history.js +78 -0
- package/dist/responder/touch-history.js.map +1 -0
- package/dist/responder/types.d.ts +63 -0
- package/dist/responder/types.js +29 -0
- package/dist/responder/types.js.map +1 -0
- package/dist/responder/use-responder.d.ts +23 -0
- package/dist/responder/use-responder.js +317 -0
- package/dist/responder/use-responder.js.map +1 -0
- package/dist/runner/host-dev.js +4 -2
- package/dist/runner/host-dev.js.map +1 -1
- package/dist/runner/host.js +6 -2
- package/dist/runner/host.js.map +1 -1
- package/dist/runner/index.js +3 -3
- package/dist/runner/index.js.map +1 -1
- package/dist/sea/gtkx-config-module.js +2 -2
- package/dist/sea/gtkx-config-module.js.map +1 -1
- package/dist/style/absolute-insets.d.ts +26 -0
- package/dist/style/absolute-insets.js +113 -0
- package/dist/style/absolute-insets.js.map +1 -0
- package/dist/style/animated-size.d.ts +25 -0
- package/dist/style/animated-size.js +225 -0
- package/dist/style/animated-size.js.map +1 -0
- package/dist/style/box-shadow.d.ts +7 -0
- package/dist/style/box-shadow.js +197 -0
- package/dist/style/box-shadow.js.map +1 -0
- package/dist/style/colors.d.ts +17 -0
- package/dist/style/colors.js +25 -6
- package/dist/style/colors.js.map +1 -1
- package/dist/style/imperative-css.d.ts +21 -0
- package/dist/style/imperative-css.js +63 -0
- package/dist/style/imperative-css.js.map +1 -0
- package/dist/style/index.d.ts +4 -1
- package/dist/style/index.js +4 -1
- package/dist/style/index.js.map +1 -1
- package/dist/style/split-style.d.ts +5 -2
- package/dist/style/split-style.js +36 -3
- package/dist/style/split-style.js.map +1 -1
- package/dist/style/text-decoration.d.ts +15 -0
- package/dist/style/text-decoration.js +26 -0
- package/dist/style/text-decoration.js.map +1 -0
- package/dist/style/visual-css.js +37 -1
- package/dist/style/visual-css.js.map +1 -1
- package/dist/svg/gradient-geometry.js +2 -5
- package/dist/svg/gradient-geometry.js.map +1 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/unsupported-export.d.ts +8 -0
- package/dist/unsupported-export.js +66 -0
- package/dist/unsupported-export.js.map +1 -0
- package/dist/vendor/react-native/pan-responder.d.ts +102 -0
- package/dist/vendor/react-native/pan-responder.js +196 -0
- package/dist/vendor/react-native/pan-responder.js.map +1 -0
- package/dist/vendor/react-native/touch-history-math.d.ts +18 -0
- package/dist/vendor/react-native/touch-history-math.js +102 -0
- package/dist/vendor/react-native/touch-history-math.js.map +1 -0
- package/dist/vite/index.d.ts +21 -8
- package/dist/vite/index.js +127 -82
- package/dist/vite/index.js.map +1 -1
- package/dist/vitest/index.d.ts +2 -2
- package/dist/vitest/index.js.map +1 -1
- package/dist/worklets-compat/index.d.ts +4 -0
- package/dist/worklets-compat/index.js +28 -0
- package/dist/worklets-compat/index.js.map +1 -0
- package/dist/worklets-compat/surface.d.ts +110 -0
- package/dist/worklets-compat/surface.js +153 -0
- package/dist/worklets-compat/surface.js.map +1 -0
- package/package.json +25 -9
- package/types.d.ts +9 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { createTouchHistory, recordTouchEnd, recordTouchMove, recordTouchStart, refreshActiveTouches, } from "./touch-history";
|
|
2
|
+
export const createResponderSystem = (options) => {
|
|
3
|
+
const registry = new Map();
|
|
4
|
+
const history = createTouchHistory();
|
|
5
|
+
let responder = null;
|
|
6
|
+
let session = null;
|
|
7
|
+
/**
|
|
8
|
+
* The registered nodes from the toplevel down to `host`, root first — RN's
|
|
9
|
+
* capture order, reversed for bubble.
|
|
10
|
+
*
|
|
11
|
+
* The walk stops wherever `parentOf` stops, which on this platform is the
|
|
12
|
+
* layout Root: an RN tree here is an island inside a native GTK widget
|
|
13
|
+
* tree (NestedRoot/IntrinsicRoot mount engines into arbitrary GTK slots),
|
|
14
|
+
* so there is no single app-wide view hierarchy to traverse. Native
|
|
15
|
+
* widgets on the way up are simply not registered and take no part.
|
|
16
|
+
*/
|
|
17
|
+
const pathOf = (host) => {
|
|
18
|
+
const path = [];
|
|
19
|
+
let current = host;
|
|
20
|
+
while (current) {
|
|
21
|
+
if (registry.has(current)) {
|
|
22
|
+
path.unshift(current);
|
|
23
|
+
}
|
|
24
|
+
current = options.parentOf(current);
|
|
25
|
+
}
|
|
26
|
+
return path;
|
|
27
|
+
};
|
|
28
|
+
const propsOf = (host) => registry.get(host)?.getProps() ?? null;
|
|
29
|
+
const createEvent = (touch, stillDown) => ({
|
|
30
|
+
nativeEvent: {
|
|
31
|
+
...touch,
|
|
32
|
+
// Single-pointer: `touches` is the still-active set (empty once the
|
|
33
|
+
// pointer is up), `changedTouches` is always this one.
|
|
34
|
+
touches: stillDown ? [touch] : [],
|
|
35
|
+
changedTouches: [touch],
|
|
36
|
+
},
|
|
37
|
+
touchHistory: history,
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* Runs a should-set handler over `path` in order, stopping at the first
|
|
41
|
+
* that returns true — RN's executeDispatchesInOrderStopAtTrue. Handlers
|
|
42
|
+
* before the winner all run, which PanResponder depends on: its capture
|
|
43
|
+
* handlers are where gestureState is initialised and where dx/dy are
|
|
44
|
+
* accumulated on move.
|
|
45
|
+
*/
|
|
46
|
+
const firstToClaim = (path, name, event) => {
|
|
47
|
+
for (const host of path) {
|
|
48
|
+
const handler = propsOf(host)?.[name];
|
|
49
|
+
if (handler?.(event) === true) {
|
|
50
|
+
return host;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
};
|
|
55
|
+
const notify = (host, name, event) => {
|
|
56
|
+
propsOf(host)?.[name]?.(event);
|
|
57
|
+
};
|
|
58
|
+
const dispatchTouch = (path, captureName, bubbleName, event) => {
|
|
59
|
+
for (const host of path) {
|
|
60
|
+
propsOf(host)?.[captureName]?.(event);
|
|
61
|
+
}
|
|
62
|
+
for (let i = path.length - 1; i >= 0; i -= 1) {
|
|
63
|
+
propsOf(path[i])?.[bubbleName]?.(event);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const grant = (host, event) => {
|
|
67
|
+
responder = host;
|
|
68
|
+
notify(host, "onResponderGrant", event);
|
|
69
|
+
// The GTK claim is per INTERACTION, not per grant: a transfer moves a JS
|
|
70
|
+
// lock, and there is nothing left to tell GTK once the sequence is
|
|
71
|
+
// already ours. Claiming again on the new holder's own gesture would
|
|
72
|
+
// deny the sequence on the source below it and silently end the drag.
|
|
73
|
+
if (session && !session.claimed) {
|
|
74
|
+
session.claimed = true;
|
|
75
|
+
options.onClaim?.(session.host);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* The negotiation path when someone already holds the responder: RN prunes
|
|
80
|
+
* it to the lowest common ancestor of the holder and the event target, and
|
|
81
|
+
* then skips the holder itself so it is never asked whether it wants what
|
|
82
|
+
* it already has. Pruning is what makes the lock transferable only
|
|
83
|
+
* UPWARDS — a descendant of the holder is not on the pruned path and
|
|
84
|
+
* cannot take it, which is RN's documented rule.
|
|
85
|
+
*
|
|
86
|
+
* Returns null when the two paths are disjoint (RNW's `lowestCommonAncestor
|
|
87
|
+
* == null`): nothing may take the responder in that case.
|
|
88
|
+
*/
|
|
89
|
+
const pruneToAncestors = (path, holder) => {
|
|
90
|
+
const holderPath = pathOf(holder);
|
|
91
|
+
let common = -1;
|
|
92
|
+
const shared = Math.min(path.length, holderPath.length);
|
|
93
|
+
for (let i = 0; i < shared && path[i] === holderPath[i]; i += 1) {
|
|
94
|
+
common = i;
|
|
95
|
+
}
|
|
96
|
+
if (common === -1) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
return path.slice(0, path[common] === holder ? common : common + 1);
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* RN's handoff, in react-native-web's order: ask the holder, then
|
|
103
|
+
* terminate it, then grant. (Upstream's ResponderEventPlugin dispatches
|
|
104
|
+
* the grant BEFORE asking, so a rejected candidate still sees
|
|
105
|
+
* `onResponderGrant` — a quirk of the pooled-event implementation rather
|
|
106
|
+
* than of the model. RN's own documentation diagram, which RNW reproduces
|
|
107
|
+
* verbatim, shows TerminationRequest -> GRANT, and that is what we do.)
|
|
108
|
+
*
|
|
109
|
+
* A holder with no `onResponderTerminationRequest` always yields: absent
|
|
110
|
+
* means "sure", in RN and in RNW alike.
|
|
111
|
+
*/
|
|
112
|
+
const attemptTransfer = (winner, event) => {
|
|
113
|
+
const holder = responder;
|
|
114
|
+
if (holder === null) {
|
|
115
|
+
grant(winner, event);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (holder === winner) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (propsOf(holder)?.onResponderTerminationRequest?.(event) === false) {
|
|
122
|
+
notify(winner, "onResponderReject", event);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
notify(holder, "onResponderTerminate", event);
|
|
126
|
+
responder = null;
|
|
127
|
+
grant(winner, event);
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Capture root-to-target, then bubble target-to-root — RN's two-phase
|
|
131
|
+
* negotiation, and the one place GTK's model and RN's agree, since GTK's
|
|
132
|
+
* CAPTURE/TARGET/BUBBLE phases run in exactly this order. We still do the
|
|
133
|
+
* walk ourselves so a single GTK event source can drive the whole path.
|
|
134
|
+
*/
|
|
135
|
+
const negotiate = (path, event, phase) => {
|
|
136
|
+
const capture = phase === "start"
|
|
137
|
+
? "onStartShouldSetResponderCapture"
|
|
138
|
+
: "onMoveShouldSetResponderCapture";
|
|
139
|
+
const bubble = phase === "start"
|
|
140
|
+
? "onStartShouldSetResponder"
|
|
141
|
+
: "onMoveShouldSetResponder";
|
|
142
|
+
const captured = firstToClaim(path, capture, event);
|
|
143
|
+
if (captured) {
|
|
144
|
+
return captured;
|
|
145
|
+
}
|
|
146
|
+
return firstToClaim([...path].reverse(), bubble, event);
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* The whole negotiation for one event: prune the path if the lock is held,
|
|
150
|
+
* ask who wants it, hand it over. Returns nothing — the caller reads
|
|
151
|
+
* `responder` afterwards, because RN dispatches `onResponderStart`/`Move`
|
|
152
|
+
* to whoever holds the lock AFTER the handoff, not before it.
|
|
153
|
+
*/
|
|
154
|
+
const negotiateAndTransfer = (path, event, phase) => {
|
|
155
|
+
const holder = responder;
|
|
156
|
+
const candidates = holder === null ? path : pruneToAncestors(path, holder);
|
|
157
|
+
if (candidates === null || candidates.length === 0) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const winner = negotiate(candidates, event, phase);
|
|
161
|
+
if (winner) {
|
|
162
|
+
attemptTransfer(winner, event);
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
const finish = (touch, terminated, touchProps) => {
|
|
166
|
+
const current = session;
|
|
167
|
+
if (!current) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
recordTouchEnd(history, touch);
|
|
171
|
+
refreshActiveTouches(history);
|
|
172
|
+
const event = createEvent(touch, false);
|
|
173
|
+
dispatchTouch(pathOf(current.host), touchProps[0], touchProps[1], event);
|
|
174
|
+
const holder = responder;
|
|
175
|
+
session = null;
|
|
176
|
+
responder = null;
|
|
177
|
+
if (holder) {
|
|
178
|
+
notify(holder, "onResponderEnd", event);
|
|
179
|
+
notify(holder, terminated ? "onResponderTerminate" : "onResponderRelease", event);
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
return {
|
|
183
|
+
register(host, getProps) {
|
|
184
|
+
registry.set(host, { getProps });
|
|
185
|
+
return () => {
|
|
186
|
+
registry.delete(host);
|
|
187
|
+
// A responder that unmounts mid-gesture cannot be asked anything
|
|
188
|
+
// ever again; drop the lock rather than stranding it.
|
|
189
|
+
if (responder === host) {
|
|
190
|
+
responder = null;
|
|
191
|
+
}
|
|
192
|
+
if (session?.host === host) {
|
|
193
|
+
session = null;
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
},
|
|
197
|
+
touchStart(host, touch) {
|
|
198
|
+
// Already tracking this press: this is an ancestor's gesture seeing the
|
|
199
|
+
// same event through GTK's bubble chain.
|
|
200
|
+
if (session !== null) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
session = {
|
|
204
|
+
host,
|
|
205
|
+
identifier: touch.identifier,
|
|
206
|
+
lastTouch: touch,
|
|
207
|
+
claimed: false,
|
|
208
|
+
};
|
|
209
|
+
recordTouchStart(history, touch);
|
|
210
|
+
refreshActiveTouches(history);
|
|
211
|
+
const path = pathOf(host);
|
|
212
|
+
const event = createEvent(touch, true);
|
|
213
|
+
dispatchTouch(path, "onTouchStartCapture", "onTouchStart", event);
|
|
214
|
+
negotiateAndTransfer(path, event, "start");
|
|
215
|
+
// RN dispatches this to whoever holds the lock once the handoff is
|
|
216
|
+
// over, which is why it is not folded into grant(): a view granted on
|
|
217
|
+
// a MOVE must not be told the interaction just started.
|
|
218
|
+
if (responder !== null) {
|
|
219
|
+
notify(responder, "onResponderStart", event);
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
touchMove(host, touch) {
|
|
223
|
+
if (session === null || session.host !== host) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
session.lastTouch = touch;
|
|
227
|
+
recordTouchMove(history, touch);
|
|
228
|
+
refreshActiveTouches(history);
|
|
229
|
+
const path = pathOf(host);
|
|
230
|
+
const event = createEvent(touch, true);
|
|
231
|
+
dispatchTouch(path, "onTouchMoveCapture", "onTouchMove", event);
|
|
232
|
+
// Two shapes go through here. Nobody holds the lock yet: the common
|
|
233
|
+
// PanResponder one, where the pan starts once
|
|
234
|
+
// onMoveShouldSetPanResponder sees enough movement. Somebody does: an
|
|
235
|
+
// ancestor may still take it over, and the move is then delivered to
|
|
236
|
+
// whoever ends up holding it — including in the same event as the
|
|
237
|
+
// handoff, exactly as RN's own state diagram shows.
|
|
238
|
+
negotiateAndTransfer(path, event, "move");
|
|
239
|
+
if (responder !== null) {
|
|
240
|
+
notify(responder, "onResponderMove", event);
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
touchEnd(host, touch) {
|
|
244
|
+
if (session === null || session.host !== host) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
finish(touch, false, ["onTouchEndCapture", "onTouchEnd"]);
|
|
248
|
+
},
|
|
249
|
+
touchCancel(host, touch) {
|
|
250
|
+
if (session === null || session.host !== host) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
finish(touch, true, ["onTouchCancelCapture", "onTouchCancel"]);
|
|
254
|
+
},
|
|
255
|
+
terminate(reason) {
|
|
256
|
+
const current = session;
|
|
257
|
+
const holder = responder;
|
|
258
|
+
if (current === null || holder === null) {
|
|
259
|
+
// Nothing holds the lock: an ancestor scrolling or a menu opening is
|
|
260
|
+
// then simply an ancestor scrolling or a menu opening. RN terminates
|
|
261
|
+
// a RESPONDER; it has nothing to say when there is not one.
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
const event = createEvent(current.lastTouch, false);
|
|
265
|
+
if (reason === "scroll" &&
|
|
266
|
+
propsOf(holder)?.onResponderTerminationRequest?.(event) === false) {
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
// No onResponderEnd here, and that is RN's shape rather than an
|
|
270
|
+
// oversight: End pairs with a touch actually ending. A termination
|
|
271
|
+
// that is not a pointer event goes straight to Terminate.
|
|
272
|
+
recordTouchEnd(history, current.lastTouch);
|
|
273
|
+
refreshActiveTouches(history);
|
|
274
|
+
session = null;
|
|
275
|
+
responder = null;
|
|
276
|
+
notify(holder, "onResponderTerminate", event);
|
|
277
|
+
return true;
|
|
278
|
+
},
|
|
279
|
+
requestResponder(host) {
|
|
280
|
+
const current = session;
|
|
281
|
+
if (current === null) {
|
|
282
|
+
// No interaction to take. A timer that fires after the pointer is up
|
|
283
|
+
// is a timer that lost, and there is nothing to negotiate over.
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
if (responder === host) {
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
const path = pathOf(current.host);
|
|
290
|
+
// A node off the interaction's path is not a candidate — the same rule
|
|
291
|
+
// the touch paths enforce by construction, stated here because this
|
|
292
|
+
// entry point is reached from a timer rather than from an event that
|
|
293
|
+
// already travelled the tree.
|
|
294
|
+
if (!path.includes(host)) {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
negotiateAndTransfer(path, createEvent(current.lastTouch, true), "move");
|
|
298
|
+
return responder === host;
|
|
299
|
+
},
|
|
300
|
+
getResponder: () => responder,
|
|
301
|
+
getSource: () => session?.host ?? null,
|
|
302
|
+
};
|
|
303
|
+
};
|
|
304
|
+
//# sourceMappingURL=system.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system.js","sourceRoot":"","sources":["../../src/responder/system.ts"],"names":[],"mappings":"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","sourcesContent":["// RN's Gesture Responder System: the negotiation, in pure JS.\n//\n// Zero @gtkx imports on purpose. Everything platform-specific enters through\n// two seams — `parentOf`, which turns a host handle into its parent, and\n// `onClaim`, the one-way GTK declaration the platform makes once per\n// interaction. That keeps the algorithm unit-testable off Linux, which\n// matters because this is the part that is subtle and the part every\n// platform historically gets wrong.\n//\n// Why reimplemented rather than reused: every other RN platform feeds\n// `topTouchStart/Move/End/Cancel` to the stock renderer's\n// ResponderEventPlugin, which lives in `facebook/react` inside\n// `react-native-renderer`. We render through `@gtkx/react` on\n// `react-reconciler`, so there is no plugin seam to feed —\n// react-native-web is in the same position and reimplemented for the same\n// reason (docs/research/gestures.md).\nimport type { NativeTouch } from \"../components/press-event\"\nimport {\n createTouchHistory,\n recordTouchEnd,\n recordTouchMove,\n recordTouchStart,\n refreshActiveTouches,\n} from \"./touch-history\"\nimport type { GestureResponderEvent, ResponderProps } from \"./types\"\n\n/** An opaque platform handle. A Gtk.Widget in practice; never treated as one. */\nexport type ResponderHost = object\n\n/**\n * Why the responder was taken away by something that is not a pointer event.\n *\n * react-native-web's list is longer — cancel-ish events, context menu,\n * window blur, ancestor scroll, selection change — and measuring GTK\n * collapsed most of it. GTK cancels a single-button gesture the instant a\n * second button goes down, and a widget that steals a sequence (a\n * selectable label, a `GtkDragSource` attached through `Controllers`)\n * cancels it too, so \"context menu\" and \"selection change\" both arrive as\n * an ordinary `::cancel` on the event source and need no trigger of their\n * own. What is left needs asking for:\n *\n * - `\"blur\"`: the toplevel stopped being the active window. Not a question,\n * in RN or here — the window is gone either way.\n * - `\"scroll\"`: an ancestor scroller moved under the gesture. The one\n * termination a holder may refuse, and therefore the only place\n * `onResponderTerminationRequest` is consulted outside a transfer (PRD\n * crux 2: GTK's `CLAIMED` is irrevocable, so anything GTK has already\n * taken cannot be given back no matter what the holder answers).\n */\nexport type TerminationReason = \"blur\" | \"scroll\"\n\nexport type ResponderSystemOptions = {\n /** The platform's parent link. Returning null ends the path. */\n parentOf: (host: ResponderHost) => ResponderHost | null\n /**\n * Fired at most ONCE per interaction, the first time any node is granted\n * the responder — where the platform makes its GTK `CLAIMED` declaration.\n *\n * Its argument is the node whose event source is carrying the interaction,\n * NOT the node that won the responder. Those differ whenever an ancestor\n * claims (the common `onMoveShouldSetPanResponder` shape), and claiming on\n * the ancestor is actively wrong: GTK denies the sequence on every gesture\n * below the one that claims, which kills the very source the interaction\n * is arriving through. What GTK is being told is \"this interaction belongs\n * to React Native, native widgets keep off\" — a statement about the\n * island, not about which view inside it currently holds the lock, which\n * is a JS matter GTK has no way to represent.\n *\n * One-way by construction: GTK has no way to hand a claimed sequence back,\n * so this only ever runs once JS has already decided (see\n * docs/research/gestures.md, \"no voluntary release\").\n */\n onClaim?: (source: ResponderHost) => void\n}\n\ntype Registration = { getProps: () => ResponderProps }\n\n// One interaction, from press to release. v1 is single-pointer: a mouse is\n// one fabricated touch, so at most one session exists at a time. It also\n// does the deduplicating — GTK delivers a press to every ancestor's gesture\n// in the bubble chain, so the second and later reports for the same press\n// find a session already open and return.\n//\n// `lastTouch` exists for termination: a window losing focus is not a pointer\n// event, and `onResponderTerminate` still has to be handed an RN-shaped\n// event. The last known position is what RN reports there too.\ntype Session = {\n host: ResponderHost\n identifier: number\n lastTouch: NativeTouch\n claimed: boolean\n}\n\nexport type ResponderSystem = {\n register(host: ResponderHost, getProps: () => ResponderProps): () => void\n touchStart(host: ResponderHost, touch: NativeTouch): void\n touchMove(host: ResponderHost, touch: NativeTouch): void\n touchEnd(host: ResponderHost, touch: NativeTouch): void\n touchCancel(host: ResponderHost, touch: NativeTouch): void\n /**\n * Something that is not a pointer event took the interaction. Returns\n * whether the responder was actually given up — `false` means either\n * nothing held it or the holder refused a reason that allows refusal.\n */\n terminate(reason: TerminationReason): boolean\n /**\n * THE OUT-OF-EVENT GRANT CHANNEL. A registered node asks for the responder\n * between touch events, and the ordinary negotiation runs against a\n * synthesized event at the last known pointer position.\n *\n * RN negotiates inside touch events only, so a recognizer that changes its\n * mind on a TIMER has no way to take the interaction until the pointer next\n * moves. `activateAfterLongPress` is exactly that recognizer: the press\n * matures while the pointer is still, and waiting for the next move puts\n * the \"lifted\" visual one frame late — or, for a press-and-hold that never\n * moves again, never.\n *\n * The precedent is react-native-web, which added\n * `onScrollShouldSetResponder` and `onSelectionChangeShouldSetResponder`\n * for its own platform's realities; extending the model where the platform\n * demands it is recorded as acceptable in docs/research/gestures.md, and\n * this channel is documented there with its reason.\n *\n * Deliberately NOT a new prop and not a new grant path: it reuses\n * `negotiateAndTransfer` unchanged, so capture still beats bubble, the LCA\n * pruning still applies, and an ancestor that wants the interaction still\n * wins it. The only thing that is new is WHEN the question gets asked. The\n * synthesized event is the same one `terminate()` already builds from\n * `session.lastTouch`, for the same reason.\n *\n * No `onResponderMove` is dispatched afterwards: the pointer did not move,\n * and inventing a move to announce a grant would put a fabricated\n * coordinate into every consumer's translation arithmetic.\n *\n * Returns whether `host` holds the responder once the negotiation is over\n * — `false` when there is no interaction, when `host` is not on the path\n * the interaction is travelling, or when somebody else won.\n */\n requestResponder(host: ResponderHost): boolean\n /** The node currently holding the responder, or null. */\n getResponder(): ResponderHost | null\n /** The node whose event source is carrying the interaction, or null. */\n getSource(): ResponderHost | null\n}\n\ntype ShouldSetName =\n | \"onStartShouldSetResponder\"\n | \"onStartShouldSetResponderCapture\"\n | \"onMoveShouldSetResponder\"\n | \"onMoveShouldSetResponderCapture\"\n\ntype NotifyName =\n | \"onResponderGrant\"\n | \"onResponderStart\"\n | \"onResponderMove\"\n | \"onResponderEnd\"\n | \"onResponderRelease\"\n | \"onResponderTerminate\"\n | \"onResponderReject\"\n\ntype TouchName =\n | \"onTouchStart\"\n | \"onTouchStartCapture\"\n | \"onTouchMove\"\n | \"onTouchMoveCapture\"\n | \"onTouchEnd\"\n | \"onTouchEndCapture\"\n | \"onTouchCancel\"\n | \"onTouchCancelCapture\"\n\nexport const createResponderSystem = (\n options: ResponderSystemOptions,\n): ResponderSystem => {\n const registry = new Map<ResponderHost, Registration>()\n const history = createTouchHistory()\n let responder: ResponderHost | null = null\n let session: Session | null = null\n\n /**\n * The registered nodes from the toplevel down to `host`, root first — RN's\n * capture order, reversed for bubble.\n *\n * The walk stops wherever `parentOf` stops, which on this platform is the\n * layout Root: an RN tree here is an island inside a native GTK widget\n * tree (NestedRoot/IntrinsicRoot mount engines into arbitrary GTK slots),\n * so there is no single app-wide view hierarchy to traverse. Native\n * widgets on the way up are simply not registered and take no part.\n */\n const pathOf = (host: ResponderHost): ResponderHost[] => {\n const path: ResponderHost[] = []\n let current: ResponderHost | null = host\n while (current) {\n if (registry.has(current)) {\n path.unshift(current)\n }\n current = options.parentOf(current)\n }\n return path\n }\n\n const propsOf = (host: ResponderHost): ResponderProps | null =>\n registry.get(host)?.getProps() ?? null\n\n const createEvent = (\n touch: NativeTouch,\n stillDown: boolean,\n ): GestureResponderEvent => ({\n nativeEvent: {\n ...touch,\n // Single-pointer: `touches` is the still-active set (empty once the\n // pointer is up), `changedTouches` is always this one.\n touches: stillDown ? [touch] : [],\n changedTouches: [touch],\n },\n touchHistory: history,\n })\n\n /**\n * Runs a should-set handler over `path` in order, stopping at the first\n * that returns true — RN's executeDispatchesInOrderStopAtTrue. Handlers\n * before the winner all run, which PanResponder depends on: its capture\n * handlers are where gestureState is initialised and where dx/dy are\n * accumulated on move.\n */\n const firstToClaim = (\n path: readonly ResponderHost[],\n name: ShouldSetName,\n event: GestureResponderEvent,\n ): ResponderHost | null => {\n for (const host of path) {\n const handler = propsOf(host)?.[name]\n if (handler?.(event) === true) {\n return host\n }\n }\n return null\n }\n\n const notify = (\n host: ResponderHost,\n name: NotifyName,\n event: GestureResponderEvent,\n ): void => {\n propsOf(host)?.[name]?.(event)\n }\n\n const dispatchTouch = (\n path: readonly ResponderHost[],\n captureName: TouchName,\n bubbleName: TouchName,\n event: GestureResponderEvent,\n ): void => {\n for (const host of path) {\n propsOf(host)?.[captureName]?.(event)\n }\n for (let i = path.length - 1; i >= 0; i -= 1) {\n propsOf(path[i]!)?.[bubbleName]?.(event)\n }\n }\n\n const grant = (host: ResponderHost, event: GestureResponderEvent): void => {\n responder = host\n notify(host, \"onResponderGrant\", event)\n // The GTK claim is per INTERACTION, not per grant: a transfer moves a JS\n // lock, and there is nothing left to tell GTK once the sequence is\n // already ours. Claiming again on the new holder's own gesture would\n // deny the sequence on the source below it and silently end the drag.\n if (session && !session.claimed) {\n session.claimed = true\n options.onClaim?.(session.host)\n }\n }\n\n /**\n * The negotiation path when someone already holds the responder: RN prunes\n * it to the lowest common ancestor of the holder and the event target, and\n * then skips the holder itself so it is never asked whether it wants what\n * it already has. Pruning is what makes the lock transferable only\n * UPWARDS — a descendant of the holder is not on the pruned path and\n * cannot take it, which is RN's documented rule.\n *\n * Returns null when the two paths are disjoint (RNW's `lowestCommonAncestor\n * == null`): nothing may take the responder in that case.\n */\n const pruneToAncestors = (\n path: readonly ResponderHost[],\n holder: ResponderHost,\n ): ResponderHost[] | null => {\n const holderPath = pathOf(holder)\n let common = -1\n const shared = Math.min(path.length, holderPath.length)\n for (let i = 0; i < shared && path[i] === holderPath[i]; i += 1) {\n common = i\n }\n if (common === -1) {\n return null\n }\n return path.slice(0, path[common] === holder ? common : common + 1)\n }\n\n /**\n * RN's handoff, in react-native-web's order: ask the holder, then\n * terminate it, then grant. (Upstream's ResponderEventPlugin dispatches\n * the grant BEFORE asking, so a rejected candidate still sees\n * `onResponderGrant` — a quirk of the pooled-event implementation rather\n * than of the model. RN's own documentation diagram, which RNW reproduces\n * verbatim, shows TerminationRequest -> GRANT, and that is what we do.)\n *\n * A holder with no `onResponderTerminationRequest` always yields: absent\n * means \"sure\", in RN and in RNW alike.\n */\n const attemptTransfer = (\n winner: ResponderHost,\n event: GestureResponderEvent,\n ): void => {\n const holder = responder\n if (holder === null) {\n grant(winner, event)\n return\n }\n if (holder === winner) {\n return\n }\n if (propsOf(holder)?.onResponderTerminationRequest?.(event) === false) {\n notify(winner, \"onResponderReject\", event)\n return\n }\n notify(holder, \"onResponderTerminate\", event)\n responder = null\n grant(winner, event)\n }\n\n /**\n * Capture root-to-target, then bubble target-to-root — RN's two-phase\n * negotiation, and the one place GTK's model and RN's agree, since GTK's\n * CAPTURE/TARGET/BUBBLE phases run in exactly this order. We still do the\n * walk ourselves so a single GTK event source can drive the whole path.\n */\n const negotiate = (\n path: readonly ResponderHost[],\n event: GestureResponderEvent,\n phase: \"start\" | \"move\",\n ): ResponderHost | null => {\n const capture =\n phase === \"start\"\n ? \"onStartShouldSetResponderCapture\"\n : \"onMoveShouldSetResponderCapture\"\n const bubble =\n phase === \"start\"\n ? \"onStartShouldSetResponder\"\n : \"onMoveShouldSetResponder\"\n const captured = firstToClaim(path, capture, event)\n if (captured) {\n return captured\n }\n return firstToClaim([...path].reverse(), bubble, event)\n }\n\n /**\n * The whole negotiation for one event: prune the path if the lock is held,\n * ask who wants it, hand it over. Returns nothing — the caller reads\n * `responder` afterwards, because RN dispatches `onResponderStart`/`Move`\n * to whoever holds the lock AFTER the handoff, not before it.\n */\n const negotiateAndTransfer = (\n path: readonly ResponderHost[],\n event: GestureResponderEvent,\n phase: \"start\" | \"move\",\n ): void => {\n const holder = responder\n const candidates = holder === null ? path : pruneToAncestors(path, holder)\n if (candidates === null || candidates.length === 0) {\n return\n }\n const winner = negotiate(candidates, event, phase)\n if (winner) {\n attemptTransfer(winner, event)\n }\n }\n\n const finish = (\n touch: NativeTouch,\n terminated: boolean,\n touchProps: [TouchName, TouchName],\n ): void => {\n const current = session\n if (!current) {\n return\n }\n recordTouchEnd(history, touch)\n refreshActiveTouches(history)\n const event = createEvent(touch, false)\n dispatchTouch(pathOf(current.host), touchProps[0], touchProps[1], event)\n\n const holder = responder\n session = null\n responder = null\n if (holder) {\n notify(holder, \"onResponderEnd\", event)\n notify(\n holder,\n terminated ? \"onResponderTerminate\" : \"onResponderRelease\",\n event,\n )\n }\n }\n\n return {\n register(host, getProps) {\n registry.set(host, { getProps })\n return () => {\n registry.delete(host)\n // A responder that unmounts mid-gesture cannot be asked anything\n // ever again; drop the lock rather than stranding it.\n if (responder === host) {\n responder = null\n }\n if (session?.host === host) {\n session = null\n }\n }\n },\n\n touchStart(host, touch) {\n // Already tracking this press: this is an ancestor's gesture seeing the\n // same event through GTK's bubble chain.\n if (session !== null) {\n return\n }\n session = {\n host,\n identifier: touch.identifier,\n lastTouch: touch,\n claimed: false,\n }\n recordTouchStart(history, touch)\n refreshActiveTouches(history)\n\n const path = pathOf(host)\n const event = createEvent(touch, true)\n dispatchTouch(path, \"onTouchStartCapture\", \"onTouchStart\", event)\n\n negotiateAndTransfer(path, event, \"start\")\n // RN dispatches this to whoever holds the lock once the handoff is\n // over, which is why it is not folded into grant(): a view granted on\n // a MOVE must not be told the interaction just started.\n if (responder !== null) {\n notify(responder, \"onResponderStart\", event)\n }\n },\n\n touchMove(host, touch) {\n if (session === null || session.host !== host) {\n return\n }\n session.lastTouch = touch\n recordTouchMove(history, touch)\n refreshActiveTouches(history)\n\n const path = pathOf(host)\n const event = createEvent(touch, true)\n dispatchTouch(path, \"onTouchMoveCapture\", \"onTouchMove\", event)\n\n // Two shapes go through here. Nobody holds the lock yet: the common\n // PanResponder one, where the pan starts once\n // onMoveShouldSetPanResponder sees enough movement. Somebody does: an\n // ancestor may still take it over, and the move is then delivered to\n // whoever ends up holding it — including in the same event as the\n // handoff, exactly as RN's own state diagram shows.\n negotiateAndTransfer(path, event, \"move\")\n if (responder !== null) {\n notify(responder, \"onResponderMove\", event)\n }\n },\n\n touchEnd(host, touch) {\n if (session === null || session.host !== host) {\n return\n }\n finish(touch, false, [\"onTouchEndCapture\", \"onTouchEnd\"])\n },\n\n touchCancel(host, touch) {\n if (session === null || session.host !== host) {\n return\n }\n finish(touch, true, [\"onTouchCancelCapture\", \"onTouchCancel\"])\n },\n\n terminate(reason) {\n const current = session\n const holder = responder\n if (current === null || holder === null) {\n // Nothing holds the lock: an ancestor scrolling or a menu opening is\n // then simply an ancestor scrolling or a menu opening. RN terminates\n // a RESPONDER; it has nothing to say when there is not one.\n return false\n }\n const event = createEvent(current.lastTouch, false)\n if (\n reason === \"scroll\" &&\n propsOf(holder)?.onResponderTerminationRequest?.(event) === false\n ) {\n return false\n }\n\n // No onResponderEnd here, and that is RN's shape rather than an\n // oversight: End pairs with a touch actually ending. A termination\n // that is not a pointer event goes straight to Terminate.\n recordTouchEnd(history, current.lastTouch)\n refreshActiveTouches(history)\n session = null\n responder = null\n notify(holder, \"onResponderTerminate\", event)\n return true\n },\n\n requestResponder(host) {\n const current = session\n if (current === null) {\n // No interaction to take. A timer that fires after the pointer is up\n // is a timer that lost, and there is nothing to negotiate over.\n return false\n }\n if (responder === host) {\n return true\n }\n const path = pathOf(current.host)\n // A node off the interaction's path is not a candidate — the same rule\n // the touch paths enforce by construction, stated here because this\n // entry point is reached from a timer rather than from an event that\n // already travelled the tree.\n if (!path.includes(host)) {\n return false\n }\n negotiateAndTransfer(path, createEvent(current.lastTouch, true), \"move\")\n return responder === host\n },\n\n getResponder: () => responder,\n getSource: () => session?.host ?? null,\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { NativeTouch, TouchHistory } from "./types";
|
|
2
|
+
export declare const createTouchHistory: () => TouchHistory;
|
|
3
|
+
export declare const recordTouchStart: (history: TouchHistory, touch: NativeTouch) => void;
|
|
4
|
+
export declare const recordTouchMove: (history: TouchHistory, touch: NativeTouch) => void;
|
|
5
|
+
export declare const recordTouchEnd: (history: TouchHistory, touch: NativeTouch) => void;
|
|
6
|
+
/**
|
|
7
|
+
* Recomputes `numberActiveTouches` and `indexOfSingleActiveTouch` — the two
|
|
8
|
+
* derived fields TouchHistoryMath's single-touch fast path reads.
|
|
9
|
+
*/
|
|
10
|
+
export declare const refreshActiveTouches: (history: TouchHistory) => void;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export const createTouchHistory = () => ({
|
|
2
|
+
touchBank: [],
|
|
3
|
+
numberActiveTouches: 0,
|
|
4
|
+
indexOfSingleActiveTouch: -1,
|
|
5
|
+
mostRecentTimeStamp: 0,
|
|
6
|
+
});
|
|
7
|
+
export const recordTouchStart = (history, touch) => {
|
|
8
|
+
const identifier = touch.identifier;
|
|
9
|
+
const existing = history.touchBank[identifier];
|
|
10
|
+
if (existing) {
|
|
11
|
+
existing.touchActive = true;
|
|
12
|
+
existing.startPageX = touch.pageX;
|
|
13
|
+
existing.startPageY = touch.pageY;
|
|
14
|
+
existing.startTimeStamp = touch.timestamp;
|
|
15
|
+
existing.currentPageX = touch.pageX;
|
|
16
|
+
existing.currentPageY = touch.pageY;
|
|
17
|
+
existing.currentTimeStamp = touch.timestamp;
|
|
18
|
+
existing.previousPageX = touch.pageX;
|
|
19
|
+
existing.previousPageY = touch.pageY;
|
|
20
|
+
existing.previousTimeStamp = touch.timestamp;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
const record = {
|
|
24
|
+
touchActive: true,
|
|
25
|
+
startPageX: touch.pageX,
|
|
26
|
+
startPageY: touch.pageY,
|
|
27
|
+
startTimeStamp: touch.timestamp,
|
|
28
|
+
currentPageX: touch.pageX,
|
|
29
|
+
currentPageY: touch.pageY,
|
|
30
|
+
currentTimeStamp: touch.timestamp,
|
|
31
|
+
previousPageX: touch.pageX,
|
|
32
|
+
previousPageY: touch.pageY,
|
|
33
|
+
previousTimeStamp: touch.timestamp,
|
|
34
|
+
};
|
|
35
|
+
history.touchBank[identifier] = record;
|
|
36
|
+
}
|
|
37
|
+
history.mostRecentTimeStamp = touch.timestamp;
|
|
38
|
+
};
|
|
39
|
+
const recordTouchMoveOrEnd = (history, touch, stillActive) => {
|
|
40
|
+
const record = history.touchBank[touch.identifier];
|
|
41
|
+
if (!record) {
|
|
42
|
+
// Upstream warns here. A move without a start means the event source and
|
|
43
|
+
// the store disagree, which is a bug in the caller, not a user error.
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
record.touchActive = stillActive;
|
|
47
|
+
record.previousPageX = record.currentPageX;
|
|
48
|
+
record.previousPageY = record.currentPageY;
|
|
49
|
+
record.previousTimeStamp = record.currentTimeStamp;
|
|
50
|
+
record.currentPageX = touch.pageX;
|
|
51
|
+
record.currentPageY = touch.pageY;
|
|
52
|
+
record.currentTimeStamp = touch.timestamp;
|
|
53
|
+
history.mostRecentTimeStamp = touch.timestamp;
|
|
54
|
+
};
|
|
55
|
+
export const recordTouchMove = (history, touch) => {
|
|
56
|
+
recordTouchMoveOrEnd(history, touch, true);
|
|
57
|
+
};
|
|
58
|
+
export const recordTouchEnd = (history, touch) => {
|
|
59
|
+
recordTouchMoveOrEnd(history, touch, false);
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Recomputes `numberActiveTouches` and `indexOfSingleActiveTouch` — the two
|
|
63
|
+
* derived fields TouchHistoryMath's single-touch fast path reads.
|
|
64
|
+
*/
|
|
65
|
+
export const refreshActiveTouches = (history) => {
|
|
66
|
+
let active = 0;
|
|
67
|
+
let singleIndex = -1;
|
|
68
|
+
for (let i = 0; i < history.touchBank.length; i += 1) {
|
|
69
|
+
const record = history.touchBank[i];
|
|
70
|
+
if (record?.touchActive) {
|
|
71
|
+
active += 1;
|
|
72
|
+
singleIndex = i;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
history.numberActiveTouches = active;
|
|
76
|
+
history.indexOfSingleActiveTouch = active === 1 ? singleIndex : -1;
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=touch-history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"touch-history.js","sourceRoot":"","sources":["../../src/responder/touch-history.ts"],"names":[],"mappings":"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","sourcesContent":["// The touch-history store, transcribed from RN's ResponderTouchHistoryStore\n// so the vendored PanResponder runs against it unmodified.\n//\n// Everything here is deliberately mechanical. The three-way split — start /\n// previous / current — is what makes velocity and clustered multi-touch\n// accumulation computable at all, and \"previous\" specifically means the\n// value before THIS event, not one frame ago. Collapsing any of it would\n// break TouchHistoryMath in ways that only show up as a subtly wrong vx.\nimport type { NativeTouch, TouchHistory, TouchRecord } from \"./types\"\n\nexport const createTouchHistory = (): TouchHistory => ({\n touchBank: [],\n numberActiveTouches: 0,\n indexOfSingleActiveTouch: -1,\n mostRecentTimeStamp: 0,\n})\n\nexport const recordTouchStart = (\n history: TouchHistory,\n touch: NativeTouch,\n): void => {\n const identifier = touch.identifier\n const existing = history.touchBank[identifier]\n if (existing) {\n existing.touchActive = true\n existing.startPageX = touch.pageX\n existing.startPageY = touch.pageY\n existing.startTimeStamp = touch.timestamp\n existing.currentPageX = touch.pageX\n existing.currentPageY = touch.pageY\n existing.currentTimeStamp = touch.timestamp\n existing.previousPageX = touch.pageX\n existing.previousPageY = touch.pageY\n existing.previousTimeStamp = touch.timestamp\n } else {\n const record: TouchRecord = {\n touchActive: true,\n startPageX: touch.pageX,\n startPageY: touch.pageY,\n startTimeStamp: touch.timestamp,\n currentPageX: touch.pageX,\n currentPageY: touch.pageY,\n currentTimeStamp: touch.timestamp,\n previousPageX: touch.pageX,\n previousPageY: touch.pageY,\n previousTimeStamp: touch.timestamp,\n }\n history.touchBank[identifier] = record\n }\n history.mostRecentTimeStamp = touch.timestamp\n}\n\nconst recordTouchMoveOrEnd = (\n history: TouchHistory,\n touch: NativeTouch,\n stillActive: boolean,\n): void => {\n const record = history.touchBank[touch.identifier]\n if (!record) {\n // Upstream warns here. A move without a start means the event source and\n // the store disagree, which is a bug in the caller, not a user error.\n return\n }\n record.touchActive = stillActive\n record.previousPageX = record.currentPageX\n record.previousPageY = record.currentPageY\n record.previousTimeStamp = record.currentTimeStamp\n record.currentPageX = touch.pageX\n record.currentPageY = touch.pageY\n record.currentTimeStamp = touch.timestamp\n history.mostRecentTimeStamp = touch.timestamp\n}\n\nexport const recordTouchMove = (\n history: TouchHistory,\n touch: NativeTouch,\n): void => {\n recordTouchMoveOrEnd(history, touch, true)\n}\n\nexport const recordTouchEnd = (\n history: TouchHistory,\n touch: NativeTouch,\n): void => {\n recordTouchMoveOrEnd(history, touch, false)\n}\n\n/**\n * Recomputes `numberActiveTouches` and `indexOfSingleActiveTouch` — the two\n * derived fields TouchHistoryMath's single-touch fast path reads.\n */\nexport const refreshActiveTouches = (history: TouchHistory): void => {\n let active = 0\n let singleIndex = -1\n for (let i = 0; i < history.touchBank.length; i += 1) {\n const record = history.touchBank[i]\n if (record?.touchActive) {\n active += 1\n singleIndex = i\n }\n }\n history.numberActiveTouches = active\n history.indexOfSingleActiveTouch = active === 1 ? singleIndex : -1\n}\n"]}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { NativeTouch, PressEvent } from "../components/press-event";
|
|
2
|
+
/** One tracked touch. Field names are RN's; do not "tidy" them. */
|
|
3
|
+
export type TouchRecord = {
|
|
4
|
+
touchActive: boolean;
|
|
5
|
+
startPageX: number;
|
|
6
|
+
startPageY: number;
|
|
7
|
+
startTimeStamp: number;
|
|
8
|
+
currentPageX: number;
|
|
9
|
+
currentPageY: number;
|
|
10
|
+
currentTimeStamp: number;
|
|
11
|
+
previousPageX: number;
|
|
12
|
+
previousPageY: number;
|
|
13
|
+
previousTimeStamp: number;
|
|
14
|
+
};
|
|
15
|
+
export type TouchHistory = {
|
|
16
|
+
touchBank: TouchRecord[];
|
|
17
|
+
numberActiveTouches: number;
|
|
18
|
+
indexOfSingleActiveTouch: number;
|
|
19
|
+
mostRecentTimeStamp: number;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* What every responder callback receives. PanResponder reads `touchHistory`
|
|
23
|
+
* off the EVENT, not off `nativeEvent` — an easy detail to get wrong, and it
|
|
24
|
+
* silently zeroes every gesture if you do.
|
|
25
|
+
*/
|
|
26
|
+
export type GestureResponderEvent = PressEvent & {
|
|
27
|
+
touchHistory: TouchHistory;
|
|
28
|
+
};
|
|
29
|
+
export type ShouldSetResponder = (event: GestureResponderEvent) => boolean;
|
|
30
|
+
/**
|
|
31
|
+
* RN's responder and touch props. The touch props fire regardless of who
|
|
32
|
+
* holds the responder; the rest are the negotiation.
|
|
33
|
+
*/
|
|
34
|
+
export type ResponderProps = {
|
|
35
|
+
onStartShouldSetResponder?: ShouldSetResponder;
|
|
36
|
+
onStartShouldSetResponderCapture?: ShouldSetResponder;
|
|
37
|
+
onMoveShouldSetResponder?: ShouldSetResponder;
|
|
38
|
+
onMoveShouldSetResponderCapture?: ShouldSetResponder;
|
|
39
|
+
onResponderGrant?: (event: GestureResponderEvent) => void | boolean;
|
|
40
|
+
onResponderStart?: (event: GestureResponderEvent) => void;
|
|
41
|
+
onResponderMove?: (event: GestureResponderEvent) => void;
|
|
42
|
+
onResponderEnd?: (event: GestureResponderEvent) => void;
|
|
43
|
+
onResponderRelease?: (event: GestureResponderEvent) => void;
|
|
44
|
+
onResponderTerminate?: (event: GestureResponderEvent) => void;
|
|
45
|
+
onResponderTerminationRequest?: ShouldSetResponder;
|
|
46
|
+
onResponderReject?: (event: GestureResponderEvent) => void;
|
|
47
|
+
onTouchStart?: (event: GestureResponderEvent) => void;
|
|
48
|
+
onTouchStartCapture?: (event: GestureResponderEvent) => void;
|
|
49
|
+
onTouchMove?: (event: GestureResponderEvent) => void;
|
|
50
|
+
onTouchMoveCapture?: (event: GestureResponderEvent) => void;
|
|
51
|
+
onTouchEnd?: (event: GestureResponderEvent) => void;
|
|
52
|
+
onTouchEndCapture?: (event: GestureResponderEvent) => void;
|
|
53
|
+
onTouchCancel?: (event: GestureResponderEvent) => void;
|
|
54
|
+
onTouchCancelCapture?: (event: GestureResponderEvent) => void;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Whether a component needs an event source at all. A View with no responder
|
|
58
|
+
* props gets no GTK controller: RN only ever asks views that declare
|
|
59
|
+
* handlers, so attaching one everywhere would be pure cost.
|
|
60
|
+
*/
|
|
61
|
+
export declare const hasResponderProps: (props: ResponderProps) => boolean;
|
|
62
|
+
/** A single touch as PanResponder's `touches`/`changedTouches` see it. */
|
|
63
|
+
export type { NativeTouch };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const RESPONDER_PROP_NAMES = [
|
|
2
|
+
"onStartShouldSetResponder",
|
|
3
|
+
"onStartShouldSetResponderCapture",
|
|
4
|
+
"onMoveShouldSetResponder",
|
|
5
|
+
"onMoveShouldSetResponderCapture",
|
|
6
|
+
"onResponderGrant",
|
|
7
|
+
"onResponderStart",
|
|
8
|
+
"onResponderMove",
|
|
9
|
+
"onResponderEnd",
|
|
10
|
+
"onResponderRelease",
|
|
11
|
+
"onResponderTerminate",
|
|
12
|
+
"onResponderTerminationRequest",
|
|
13
|
+
"onResponderReject",
|
|
14
|
+
"onTouchStart",
|
|
15
|
+
"onTouchStartCapture",
|
|
16
|
+
"onTouchMove",
|
|
17
|
+
"onTouchMoveCapture",
|
|
18
|
+
"onTouchEnd",
|
|
19
|
+
"onTouchEndCapture",
|
|
20
|
+
"onTouchCancel",
|
|
21
|
+
"onTouchCancelCapture",
|
|
22
|
+
];
|
|
23
|
+
/**
|
|
24
|
+
* Whether a component needs an event source at all. A View with no responder
|
|
25
|
+
* props gets no GTK controller: RN only ever asks views that declare
|
|
26
|
+
* handlers, so attaching one everywhere would be pure cost.
|
|
27
|
+
*/
|
|
28
|
+
export const hasResponderProps = (props) => RESPONDER_PROP_NAMES.some((name) => props[name] !== undefined);
|
|
29
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/responder/types.ts"],"names":[],"mappings":"AA2EA,MAAM,oBAAoB,GAAG;IAC3B,2BAA2B;IAC3B,kCAAkC;IAClC,0BAA0B;IAC1B,iCAAiC;IACjC,kBAAkB;IAClB,kBAAkB;IAClB,iBAAiB;IACjB,gBAAgB;IAChB,oBAAoB;IACpB,sBAAsB;IACtB,+BAA+B;IAC/B,mBAAmB;IACnB,cAAc;IACd,qBAAqB;IACrB,aAAa;IACb,oBAAoB;IACpB,YAAY;IACZ,mBAAmB;IACnB,eAAe;IACf,sBAAsB;CAC8B,CAAA;AAEtD;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAqB,EAAW,EAAE,CAClE,oBAAoB,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,CAAA","sourcesContent":["// The responder system's public vocabulary: the touch-history shape RN's\n// PanResponder expects, and the props a View accepts.\n//\n// The touch-history shape is not ours to design. react-native-web proved\n// that RN's own PanResponder runs unmodified on a foreign platform provided\n// this structure is reproduced exactly — field for field, including the\n// three-way current/previous/start split and the millisecond timestamps —\n// so it is transcribed from ResponderTouchHistoryStore rather than invented.\nimport type { NativeTouch, PressEvent } from \"../components/press-event\"\n\n/** One tracked touch. Field names are RN's; do not \"tidy\" them. */\nexport type TouchRecord = {\n touchActive: boolean\n startPageX: number\n startPageY: number\n startTimeStamp: number\n currentPageX: number\n currentPageY: number\n currentTimeStamp: number\n previousPageX: number\n previousPageY: number\n previousTimeStamp: number\n}\n\nexport type TouchHistory = {\n // Sparse: indexed by touch identifier, exactly as RN does it.\n touchBank: TouchRecord[]\n numberActiveTouches: number\n // Only meaningful when numberActiveTouches === 1; TouchHistoryMath's fast\n // path reads it directly.\n indexOfSingleActiveTouch: number\n mostRecentTimeStamp: number\n}\n\n/**\n * What every responder callback receives. PanResponder reads `touchHistory`\n * off the EVENT, not off `nativeEvent` — an easy detail to get wrong, and it\n * silently zeroes every gesture if you do.\n */\nexport type GestureResponderEvent = PressEvent & {\n touchHistory: TouchHistory\n}\n\nexport type ShouldSetResponder = (event: GestureResponderEvent) => boolean\n\n/**\n * RN's responder and touch props. The touch props fire regardless of who\n * holds the responder; the rest are the negotiation.\n */\nexport type ResponderProps = {\n onStartShouldSetResponder?: ShouldSetResponder\n onStartShouldSetResponderCapture?: ShouldSetResponder\n onMoveShouldSetResponder?: ShouldSetResponder\n onMoveShouldSetResponderCapture?: ShouldSetResponder\n // RN lets onResponderGrant return a boolean (onShouldBlockNativeResponder);\n // PanResponder's does. Nothing consumes it here yet — see docs/api.md.\n onResponderGrant?: (event: GestureResponderEvent) => void | boolean\n onResponderStart?: (event: GestureResponderEvent) => void\n onResponderMove?: (event: GestureResponderEvent) => void\n onResponderEnd?: (event: GestureResponderEvent) => void\n onResponderRelease?: (event: GestureResponderEvent) => void\n onResponderTerminate?: (event: GestureResponderEvent) => void\n onResponderTerminationRequest?: ShouldSetResponder\n onResponderReject?: (event: GestureResponderEvent) => void\n\n onTouchStart?: (event: GestureResponderEvent) => void\n onTouchStartCapture?: (event: GestureResponderEvent) => void\n onTouchMove?: (event: GestureResponderEvent) => void\n onTouchMoveCapture?: (event: GestureResponderEvent) => void\n onTouchEnd?: (event: GestureResponderEvent) => void\n onTouchEndCapture?: (event: GestureResponderEvent) => void\n onTouchCancel?: (event: GestureResponderEvent) => void\n onTouchCancelCapture?: (event: GestureResponderEvent) => void\n}\n\nconst RESPONDER_PROP_NAMES = [\n \"onStartShouldSetResponder\",\n \"onStartShouldSetResponderCapture\",\n \"onMoveShouldSetResponder\",\n \"onMoveShouldSetResponderCapture\",\n \"onResponderGrant\",\n \"onResponderStart\",\n \"onResponderMove\",\n \"onResponderEnd\",\n \"onResponderRelease\",\n \"onResponderTerminate\",\n \"onResponderTerminationRequest\",\n \"onResponderReject\",\n \"onTouchStart\",\n \"onTouchStartCapture\",\n \"onTouchMove\",\n \"onTouchMoveCapture\",\n \"onTouchEnd\",\n \"onTouchEndCapture\",\n \"onTouchCancel\",\n \"onTouchCancelCapture\",\n] as const satisfies readonly (keyof ResponderProps)[]\n\n/**\n * Whether a component needs an event source at all. A View with no responder\n * props gets no GTK controller: RN only ever asks views that declare\n * handlers, so attaching one everywhere would be pure cost.\n */\nexport const hasResponderProps = (props: ResponderProps): boolean =>\n RESPONDER_PROP_NAMES.some((name) => props[name] !== undefined)\n\n/** A single touch as PanResponder's `touches`/`changedTouches` see it. */\nexport type { NativeTouch }\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type RefObject } from "react";
|
|
2
|
+
import { Gtk } from "../gtkx/bridge/index";
|
|
3
|
+
import { type ResponderHost } from "./system";
|
|
4
|
+
import { type ResponderProps } from "./types";
|
|
5
|
+
/** Exposed for tests and for future ScrollView arbitration. */
|
|
6
|
+
export declare const getCurrentResponder: () => ResponderHost | null;
|
|
7
|
+
/**
|
|
8
|
+
* The out-of-event grant channel, for a recognizer whose mind was changed by
|
|
9
|
+
* a timer rather than by a pointer (`activateAfterLongPress`). See
|
|
10
|
+
* `ResponderSystem.requestResponder` for what it does and
|
|
11
|
+
* docs/research/gestures.md for why the model is extended at all.
|
|
12
|
+
*
|
|
13
|
+
* @internal Not part of the RN surface: an app writes responder props, and
|
|
14
|
+
* nothing in RN asks for the responder from outside an event. This exists for
|
|
15
|
+
* `GestureDetector`, whose recognizers do.
|
|
16
|
+
*/
|
|
17
|
+
export declare const requestResponder: (widget: Gtk.Widget) => boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Attaches the responder event source to a component's widget, but only when
|
|
20
|
+
* it actually declares responder props — RN never asks a view without
|
|
21
|
+
* handlers, so a controller on every View would be pure cost.
|
|
22
|
+
*/
|
|
23
|
+
export declare const useResponder: (widgetRef: RefObject<Gtk.Widget | null>, props: ResponderProps) => void;
|