basalt-core 0.0.0-rc5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cli/basalt.d.ts +3 -0
  3. package/dist/cli/basalt.d.ts.map +1 -0
  4. package/dist/cli/basalt.js +47 -0
  5. package/dist/cli/basalt.js.map +1 -0
  6. package/dist/cli/bundle-cli.d.ts +12 -0
  7. package/dist/cli/bundle-cli.d.ts.map +1 -0
  8. package/dist/cli/bundle-cli.js +124 -0
  9. package/dist/cli/bundle-cli.js.map +1 -0
  10. package/dist/cli/bundleWithAssets.d.ts +79 -0
  11. package/dist/cli/bundleWithAssets.d.ts.map +1 -0
  12. package/dist/cli/bundleWithAssets.js +198 -0
  13. package/dist/cli/bundleWithAssets.js.map +1 -0
  14. package/dist/cli/desktop.d.ts +339 -0
  15. package/dist/cli/desktop.d.ts.map +1 -0
  16. package/dist/cli/desktop.js +1029 -0
  17. package/dist/cli/desktop.js.map +1 -0
  18. package/dist/cli/doctor.d.ts +31 -0
  19. package/dist/cli/doctor.d.ts.map +1 -0
  20. package/dist/cli/doctor.js +283 -0
  21. package/dist/cli/doctor.js.map +1 -0
  22. package/dist/cli/init.d.ts +77 -0
  23. package/dist/cli/init.d.ts.map +1 -0
  24. package/dist/cli/init.js +442 -0
  25. package/dist/cli/init.js.map +1 -0
  26. package/dist/cli/metro.d.ts +49 -0
  27. package/dist/cli/metro.d.ts.map +1 -0
  28. package/dist/cli/metro.js +148 -0
  29. package/dist/cli/metro.js.map +1 -0
  30. package/dist/cli/packageApp.d.ts +102 -0
  31. package/dist/cli/packageApp.d.ts.map +1 -0
  32. package/dist/cli/packageApp.js +319 -0
  33. package/dist/cli/packageApp.js.map +1 -0
  34. package/dist/cli/steps.d.ts +34 -0
  35. package/dist/cli/steps.d.ts.map +1 -0
  36. package/dist/cli/steps.js +53 -0
  37. package/dist/cli/steps.js.map +1 -0
  38. package/dist/metro-config.d.ts +168 -0
  39. package/dist/metro-config.d.ts.map +1 -0
  40. package/dist/metro-config.js +671 -0
  41. package/dist/metro-config.js.map +1 -0
  42. package/dist/react-native.config.d.ts +7 -0
  43. package/dist/react-native.config.d.ts.map +1 -0
  44. package/dist/react-native.config.js +80 -0
  45. package/dist/react-native.config.js.map +1 -0
  46. package/dist/src/DragSource.d.ts +52 -0
  47. package/dist/src/DragSource.d.ts.map +1 -0
  48. package/dist/src/DragSource.js +97 -0
  49. package/dist/src/DragSource.js.map +1 -0
  50. package/dist/src/DropTarget.d.ts +58 -0
  51. package/dist/src/DropTarget.d.ts.map +1 -0
  52. package/dist/src/DropTarget.js +131 -0
  53. package/dist/src/DropTarget.js.map +1 -0
  54. package/dist/src/KeyHandler.d.ts +57 -0
  55. package/dist/src/KeyHandler.d.ts.map +1 -0
  56. package/dist/src/KeyHandler.js +48 -0
  57. package/dist/src/KeyHandler.js.map +1 -0
  58. package/dist/src/Menu.d.ts +72 -0
  59. package/dist/src/Menu.d.ts.map +1 -0
  60. package/dist/src/Menu.js +179 -0
  61. package/dist/src/Menu.js.map +1 -0
  62. package/dist/src/TitleBar.d.ts +75 -0
  63. package/dist/src/TitleBar.d.ts.map +1 -0
  64. package/dist/src/TitleBar.js +236 -0
  65. package/dist/src/TitleBar.js.map +1 -0
  66. package/dist/src/Window.d.ts +87 -0
  67. package/dist/src/Window.d.ts.map +1 -0
  68. package/dist/src/Window.js +248 -0
  69. package/dist/src/Window.js.map +1 -0
  70. package/dist/src/closeRequest.d.ts +55 -0
  71. package/dist/src/closeRequest.d.ts.map +1 -0
  72. package/dist/src/closeRequest.js +134 -0
  73. package/dist/src/closeRequest.js.map +1 -0
  74. package/dist/src/index.d.ts +45 -0
  75. package/dist/src/index.d.ts.map +1 -0
  76. package/dist/src/index.js +92 -0
  77. package/dist/src/index.js.map +1 -0
  78. package/dist/src/overrides/Alert.d.ts +69 -0
  79. package/dist/src/overrides/Alert.d.ts.map +1 -0
  80. package/dist/src/overrides/Alert.js +112 -0
  81. package/dist/src/overrides/Alert.js.map +1 -0
  82. package/dist/src/overrides/BaseViewConfig.d.ts +28 -0
  83. package/dist/src/overrides/BaseViewConfig.d.ts.map +1 -0
  84. package/dist/src/overrides/BaseViewConfig.js +72 -0
  85. package/dist/src/overrides/BaseViewConfig.js.map +1 -0
  86. package/dist/src/overrides/Platform.linux.d.ts +10 -0
  87. package/dist/src/overrides/Platform.linux.d.ts.map +1 -0
  88. package/dist/src/overrides/Platform.linux.js +15 -0
  89. package/dist/src/overrides/Platform.linux.js.map +1 -0
  90. package/dist/src/overrides/Platform.macos.d.ts +10 -0
  91. package/dist/src/overrides/Platform.macos.d.ts.map +1 -0
  92. package/dist/src/overrides/Platform.macos.js +15 -0
  93. package/dist/src/overrides/Platform.macos.js.map +1 -0
  94. package/dist/src/overrides/Platform.windows.d.ts +10 -0
  95. package/dist/src/overrides/Platform.windows.d.ts.map +1 -0
  96. package/dist/src/overrides/Platform.windows.js +15 -0
  97. package/dist/src/overrides/Platform.windows.js.map +1 -0
  98. package/dist/src/overrides/ReactDevToolsSettingsManager.d.ts +24 -0
  99. package/dist/src/overrides/ReactDevToolsSettingsManager.d.ts.map +1 -0
  100. package/dist/src/overrides/ReactDevToolsSettingsManager.js +30 -0
  101. package/dist/src/overrides/ReactDevToolsSettingsManager.js.map +1 -0
  102. package/dist/src/overrides/RefreshControl.d.ts +52 -0
  103. package/dist/src/overrides/RefreshControl.d.ts.map +1 -0
  104. package/dist/src/overrides/RefreshControl.js +92 -0
  105. package/dist/src/overrides/RefreshControl.js.map +1 -0
  106. package/dist/src/overrides/ScrollView.d.ts +39 -0
  107. package/dist/src/overrides/ScrollView.d.ts.map +1 -0
  108. package/dist/src/overrides/ScrollView.js +59 -0
  109. package/dist/src/overrides/ScrollView.js.map +1 -0
  110. package/dist/src/overrides/Share.d.ts +96 -0
  111. package/dist/src/overrides/Share.d.ts.map +1 -0
  112. package/dist/src/overrides/Share.js +97 -0
  113. package/dist/src/overrides/Share.js.map +1 -0
  114. package/dist/src/overrides/TextInput.d.ts +81 -0
  115. package/dist/src/overrides/TextInput.d.ts.map +1 -0
  116. package/dist/src/overrides/TextInput.js +213 -0
  117. package/dist/src/overrides/TextInput.js.map +1 -0
  118. package/dist/src/overrides/View.d.ts +36 -0
  119. package/dist/src/overrides/View.d.ts.map +1 -0
  120. package/dist/src/overrides/View.js +99 -0
  121. package/dist/src/overrides/View.js.map +1 -0
  122. package/dist/src/overrides/createPlatform.d.ts +32 -0
  123. package/dist/src/overrides/createPlatform.d.ts.map +1 -0
  124. package/dist/src/overrides/createPlatform.js +84 -0
  125. package/dist/src/overrides/createPlatform.js.map +1 -0
  126. package/dist/src/overrides/setUpDeveloperTools.d.ts +28 -0
  127. package/dist/src/overrides/setUpDeveloperTools.d.ts.map +1 -0
  128. package/dist/src/overrides/setUpDeveloperTools.js +84 -0
  129. package/dist/src/overrides/setUpDeveloperTools.js.map +1 -0
  130. package/dist/src/overrides/setUpXHR.d.ts +46 -0
  131. package/dist/src/overrides/setUpXHR.d.ts.map +1 -0
  132. package/dist/src/overrides/setUpXHR.js +236 -0
  133. package/dist/src/overrides/setUpXHR.js.map +1 -0
  134. package/dist/src/quitRequest.d.ts +55 -0
  135. package/dist/src/quitRequest.d.ts.map +1 -0
  136. package/dist/src/quitRequest.js +121 -0
  137. package/dist/src/quitRequest.js.map +1 -0
  138. package/dist/src/resourcePath.d.ts +18 -0
  139. package/dist/src/resourcePath.d.ts.map +1 -0
  140. package/dist/src/resourcePath.js +31 -0
  141. package/dist/src/resourcePath.js.map +1 -0
  142. package/dist/src/responseBody.d.ts +76 -0
  143. package/dist/src/responseBody.d.ts.map +1 -0
  144. package/dist/src/responseBody.js +94 -0
  145. package/dist/src/responseBody.js.map +1 -0
  146. package/dist/src/responseHeaders.d.ts +40 -0
  147. package/dist/src/responseHeaders.d.ts.map +1 -0
  148. package/dist/src/responseHeaders.js +75 -0
  149. package/dist/src/responseHeaders.js.map +1 -0
  150. package/dist/src/titleBarState.d.ts +43 -0
  151. package/dist/src/titleBarState.d.ts.map +1 -0
  152. package/dist/src/titleBarState.js +77 -0
  153. package/dist/src/titleBarState.js.map +1 -0
  154. package/dist/src/useContextMenu.d.ts +113 -0
  155. package/dist/src/useContextMenu.d.ts.map +1 -0
  156. package/dist/src/useContextMenu.js +109 -0
  157. package/dist/src/useContextMenu.js.map +1 -0
  158. package/dist/src/useDialog.d.ts +98 -0
  159. package/dist/src/useDialog.d.ts.map +1 -0
  160. package/dist/src/useDialog.js +112 -0
  161. package/dist/src/useDialog.js.map +1 -0
  162. package/dist/src/useDisplays.d.ts +70 -0
  163. package/dist/src/useDisplays.d.ts.map +1 -0
  164. package/dist/src/useDisplays.js +118 -0
  165. package/dist/src/useDisplays.js.map +1 -0
  166. package/dist/src/useHandledKeys.d.ts +38 -0
  167. package/dist/src/useHandledKeys.d.ts.map +1 -0
  168. package/dist/src/useHandledKeys.js +70 -0
  169. package/dist/src/useHandledKeys.js.map +1 -0
  170. package/dist/src/useWindow.d.ts +140 -0
  171. package/dist/src/useWindow.d.ts.map +1 -0
  172. package/dist/src/useWindow.js +233 -0
  173. package/dist/src/useWindow.js.map +1 -0
  174. package/dist/tsconfig.tsbuildinfo +1 -0
  175. package/native/CMakeLists.txt +355 -0
  176. package/native/bootstrap.sh +613 -0
  177. package/native/cmake/CompilerFlags.cmake +49 -0
  178. package/native/cmake/Expo.cmake +125 -0
  179. package/native/cmake/ReactNativeCore.cmake +612 -0
  180. package/native/cmake/Reanimated.cmake +108 -0
  181. package/native/cmake/Skia.cmake +379 -0
  182. package/native/cmake/ThirdParty.cmake +290 -0
  183. package/native/cmake/Worklets.cmake +67 -0
  184. package/native/cmake/codegen/CMakeLists.txt +32 -0
  185. package/native/core/AppIdentity.cpp +85 -0
  186. package/native/core/AppIdentity.h +59 -0
  187. package/native/core/AppPaths.cpp +96 -0
  188. package/native/core/AppPaths.h +53 -0
  189. package/native/core/AppearanceModule.cpp +60 -0
  190. package/native/core/AppearanceModule.h +40 -0
  191. package/native/core/Backface.h +59 -0
  192. package/native/core/BlobModule.cpp +283 -0
  193. package/native/core/BlobModule.h +76 -0
  194. package/native/core/BlobRegistry.cpp +75 -0
  195. package/native/core/BlobRegistry.h +44 -0
  196. package/native/core/ColorScheme.cpp +105 -0
  197. package/native/core/ColorScheme.h +59 -0
  198. package/native/core/ComponentRegistry.h +30 -0
  199. package/native/core/ControlMetrics.h +37 -0
  200. package/native/core/CoreModules.cpp +592 -0
  201. package/native/core/CoreModules.h +308 -0
  202. package/native/core/DebuggingOverlay.cpp +106 -0
  203. package/native/core/DebuggingOverlay.h +65 -0
  204. package/native/core/DesktopControls.cpp +232 -0
  205. package/native/core/DesktopControls.h +170 -0
  206. package/native/core/DevBundle.cpp +108 -0
  207. package/native/core/DevBundle.h +69 -0
  208. package/native/core/DevMenu.cpp +99 -0
  209. package/native/core/DevMenu.h +75 -0
  210. package/native/core/DialogModule.cpp +150 -0
  211. package/native/core/DialogModule.h +51 -0
  212. package/native/core/DragAndDrop.cpp +45 -0
  213. package/native/core/DragAndDrop.h +225 -0
  214. package/native/core/ExpoImageComponent.cpp +79 -0
  215. package/native/core/ExpoImageComponent.h +80 -0
  216. package/native/core/ExpoModules.cpp +415 -0
  217. package/native/core/ExpoModules.h +115 -0
  218. package/native/core/ExpoRuntime.cpp +366 -0
  219. package/native/core/ExpoRuntime.h +42 -0
  220. package/native/core/FocusRing.h +36 -0
  221. package/native/core/FontRegistry.h +51 -0
  222. package/native/core/GestureHandlerModule.cpp +136 -0
  223. package/native/core/GestureHandlerModule.h +71 -0
  224. package/native/core/Gestures.cpp +533 -0
  225. package/native/core/Gestures.h +145 -0
  226. package/native/core/HoverTracker.cpp +69 -0
  227. package/native/core/HoverTracker.h +109 -0
  228. package/native/core/HttpClient.cpp +282 -0
  229. package/native/core/ImageBytes.cpp +205 -0
  230. package/native/core/ImageBytes.h +29 -0
  231. package/native/core/ImageCache.cpp +51 -0
  232. package/native/core/ImageCache.h +89 -0
  233. package/native/core/JsRuntimeAccess.cpp +70 -0
  234. package/native/core/JsRuntimeAccess.h +60 -0
  235. package/native/core/JsiPromise.h +51 -0
  236. package/native/core/KeyEvents.cpp +116 -0
  237. package/native/core/KeyEvents.h +144 -0
  238. package/native/core/LogBoxSurface.cpp +46 -0
  239. package/native/core/LogBoxSurface.h +68 -0
  240. package/native/core/MenuModel.h +117 -0
  241. package/native/core/MenuModule.cpp +209 -0
  242. package/native/core/MenuModule.h +66 -0
  243. package/native/core/MountingWalk.h +524 -0
  244. package/native/core/PackageModules.cpp.in +25 -0
  245. package/native/core/PackageModules.h +50 -0
  246. package/native/core/PlatformConstantsModule.cpp +63 -0
  247. package/native/core/PlatformConstantsModule.h +64 -0
  248. package/native/core/PlatformServices.h +213 -0
  249. package/native/core/PointerButtons.h +63 -0
  250. package/native/core/PullToRefresh.cpp +57 -0
  251. package/native/core/PullToRefresh.h +73 -0
  252. package/native/core/ReanimatedCompat.h +47 -0
  253. package/native/core/ReanimatedModule.cpp +203 -0
  254. package/native/core/ReanimatedModule.h +55 -0
  255. package/native/core/ScrollAnimation.cpp +59 -0
  256. package/native/core/ScrollAnimation.h +70 -0
  257. package/native/core/ScrollBounds.cpp +26 -0
  258. package/native/core/ScrollBounds.h +68 -0
  259. package/native/core/ScrollIndicator.cpp +50 -0
  260. package/native/core/ScrollIndicator.h +69 -0
  261. package/native/core/ScrollMomentum.cpp +71 -0
  262. package/native/core/ScrollMomentum.h +73 -0
  263. package/native/core/ScrollSnap.cpp +123 -0
  264. package/native/core/ScrollSnap.h +80 -0
  265. package/native/core/ShareFallback.cpp +101 -0
  266. package/native/core/ShareFallback.h +45 -0
  267. package/native/core/SkiaPictureViewComponent.cpp +11 -0
  268. package/native/core/SkiaPictureViewComponent.h +47 -0
  269. package/native/core/SourceCodeModule.cpp +55 -0
  270. package/native/core/SourceCodeModule.h +53 -0
  271. package/native/core/StatusBarModule.cpp +23 -0
  272. package/native/core/StatusBarModule.h +42 -0
  273. package/native/core/TestDialog.cpp +148 -0
  274. package/native/core/TestDialog.h +96 -0
  275. package/native/core/TestKeys.cpp +78 -0
  276. package/native/core/TestKeys.h +50 -0
  277. package/native/core/TestQuitFile.cpp +33 -0
  278. package/native/core/TestQuitFile.h +60 -0
  279. package/native/core/TestSettle.h +192 -0
  280. package/native/core/TitleBarRegions.h +31 -0
  281. package/native/core/TurboModuleProxy.cpp +51 -0
  282. package/native/core/TurboModuleProxy.h +46 -0
  283. package/native/core/UIManagerAccess.cpp +43 -0
  284. package/native/core/UIManagerAccess.h +43 -0
  285. package/native/core/WindowBoundsCache.cpp +319 -0
  286. package/native/core/WindowControl.h +235 -0
  287. package/native/core/WindowHost.h +158 -0
  288. package/native/core/WindowMethods.cpp +167 -0
  289. package/native/core/WindowMethods.h +84 -0
  290. package/native/core/WindowsModule.cpp +448 -0
  291. package/native/core/WindowsModule.h +133 -0
  292. package/native/core/WorkletsModule.cpp +199 -0
  293. package/native/core/WorkletsModule.h +57 -0
  294. package/native/core/portability_probe.cpp +210 -0
  295. package/native/tests/EventRecorder.h +124 -0
  296. package/native/tests/TestHarness.cpp +109 -0
  297. package/native/tests/TestHarness.h +89 -0
  298. package/native/tests/TreeDump.h +49 -0
  299. package/native/tests/test_app_identity.cpp +114 -0
  300. package/native/tests/test_app_paths.cpp +48 -0
  301. package/native/tests/test_appearance.cpp +107 -0
  302. package/native/tests/test_backface.cpp +79 -0
  303. package/native/tests/test_blobs.cpp +157 -0
  304. package/native/tests/test_controls.cpp +185 -0
  305. package/native/tests/test_devbundle.cpp +103 -0
  306. package/native/tests/test_drag_and_drop.cpp +143 -0
  307. package/native/tests/test_gestures.cpp +331 -0
  308. package/native/tests/test_hover.cpp +92 -0
  309. package/native/tests/test_image_cache.cpp +109 -0
  310. package/native/tests/test_js_runtime_access.cpp +137 -0
  311. package/native/tests/test_key_events.cpp +235 -0
  312. package/native/tests/test_momentum.cpp +138 -0
  313. package/native/tests/test_quit_file.cpp +104 -0
  314. package/native/tests/test_scroll_animation.cpp +120 -0
  315. package/native/tests/test_scroll_bounds.cpp +66 -0
  316. package/native/tests/test_scroll_indicator.cpp +149 -0
  317. package/native/tests/test_scroll_snap.cpp +112 -0
  318. package/native/tests/test_settle.cpp +115 -0
  319. package/native/tests/test_share.cpp +75 -0
  320. package/native/tests/test_sourcecode.cpp +62 -0
  321. package/native/tests/test_window_close.cpp +119 -0
  322. package/native/tests/test_window_limits.cpp +123 -0
  323. package/package.json +43 -0
  324. package/react-native.config.js +86 -0
  325. package/supported-versions.json +66 -0
@@ -0,0 +1,64 @@
1
+ // The `PlatformConstants` TurboModule, replacing ReactCxxPlatform's.
2
+ //
3
+ // ReactCxxPlatform ships one, and it hardcodes a React Native version of
4
+ // 1000.0.0 -- the placeholder `main` uses for "not a release" -- in every
5
+ // version, releases included. React Native's JavaScript compares that against
6
+ // the version the bundle was built from and, in a development build, reports
7
+ //
8
+ // React Native version mismatch.
9
+ // JavaScript version: 0.87.1
10
+ // Native version: 1000.0.0
11
+ //
12
+ // which is a `console.error`, so it is noise rather than a crash, but it is
13
+ // noise that every developer on a released version would see forever, and it
14
+ // tells them to do things that will not help. So this reports the version the
15
+ // host was actually built against, which CMake reads out of React Native's own
16
+ // package.json and passes in as BASALT_REACT_NATIVE_VERSION.
17
+ //
18
+ // Worth reporting upstream: nothing in ReactCxxPlatform can match a release
19
+ // while that constant is baked in.
20
+ //
21
+ // Everything else is copied from ReactCxxPlatform's implementation, including
22
+ // the Android-shaped fields, because that is the spec this platform answers.
23
+ // See packages/basalt-core/src/overrides/createPlatform.js for why the
24
+ // Android spec is the right one here.
25
+
26
+ #pragma once
27
+
28
+ #include <react/coremodules/PlatformConstantsModule.h>
29
+
30
+ #include <string>
31
+
32
+ namespace basalt {
33
+
34
+ // Note the base class: the generated spec binds each method to the class it is
35
+ // templated on, at compile time, so subclassing ReactCxxPlatform's module and
36
+ // overriding getConstants does nothing at all -- the method table still points
37
+ // at the base. It has to derive from the spec itself. That failure is silent
38
+ // and looks exactly like the provider not being consulted.
39
+ class DesktopPlatformConstantsModule
40
+ : public facebook::react::NativePlatformConstantsAndroidCxxSpec<DesktopPlatformConstantsModule> {
41
+ public:
42
+ explicit DesktopPlatformConstantsModule(std::shared_ptr<facebook::react::CallInvoker> jsInvoker)
43
+ : NativePlatformConstantsAndroidCxxSpec(std::move(jsInvoker)) {}
44
+
45
+ std::string getAndroidID(facebook::jsi::Runtime & /*rt*/) {
46
+ return "";
47
+ }
48
+
49
+ facebook::react::PlatformConstantsAndroid getConstants(facebook::jsi::Runtime &rt);
50
+
51
+ // Parses "0.87.1" or "0.88.0-rc.2". Exposed for the tests, which is the only
52
+ // way to be sure a prerelease tag does not silently become part of the patch
53
+ // number. The tag itself is not reported: the Android spec types it as an
54
+ // optional int, so "rc.2" cannot be expressed.
55
+ struct Version {
56
+ int major{0};
57
+ int minor{0};
58
+ int patch{0};
59
+ std::string prerelease;
60
+ };
61
+ static Version parseVersion(const std::string &text);
62
+ };
63
+
64
+ } // namespace basalt
@@ -0,0 +1,213 @@
1
+ // The handful of things a core module needs an operating system for.
2
+ //
3
+ // One file rather than five seams, because each of these is two or three
4
+ // functions and splitting them would mean ten files saying very little. What
5
+ // they have in common is that the *module* above each is portable and only the
6
+ // last step is not: putting text on a clipboard, handing a URL to whatever
7
+ // opens it, and putting a modal dialog on screen.
8
+ //
9
+ // The fifth seam, after fonts, the text layout manager, the component registry
10
+ // and the colour scheme.
11
+
12
+ #pragma once
13
+
14
+ #include <functional>
15
+ #include <string>
16
+ #include <vector>
17
+
18
+ namespace basalt {
19
+
20
+ // --- Clipboard ---------------------------------------------------------------
21
+
22
+ // The clipboard's text, or empty if it holds none. Called on the main thread.
23
+ std::string clipboardText();
24
+ void setClipboardText(const std::string &text);
25
+
26
+ // --- Opening things ----------------------------------------------------------
27
+
28
+ // Whether anything is registered to handle this URL. A desktop cannot always
29
+ // answer honestly -- both implementations here check the scheme rather than
30
+ // asking every installed application -- so this errs towards yes.
31
+ bool canOpenUrl(const std::string &url);
32
+
33
+ // Hands the URL to the desktop. Returns false if it could not be launched.
34
+ bool openUrl(const std::string &url);
35
+
36
+ // --- Alerts ------------------------------------------------------------------
37
+
38
+ struct AlertRequest {
39
+ std::string title;
40
+ std::string message;
41
+ // In React Native's order, which is also the order the callback reports.
42
+ std::vector<std::string> buttons;
43
+ // A `prompt`, with the text field pre-filled. Empty means a plain alert.
44
+ bool hasTextInput{false};
45
+ std::string defaultText;
46
+ std::string placeholder;
47
+ };
48
+
49
+ // Shows a modal alert and calls `onButton` with the index of the button
50
+ // pressed, and the text if the alert had a field.
51
+ //
52
+ // Must not block: it is called from the JavaScript thread's mount step, and a
53
+ // modal run loop there would deadlock the runtime. Implementations marshal to
54
+ // the main thread and return at once.
55
+ using AlertCallback = std::function<void(int buttonIndex, const std::string &text)>;
56
+ void showAlert(const AlertRequest &request, AlertCallback onButton);
57
+
58
+ // --- File dialogs -------------------------------------------------------------
59
+
60
+ // One entry in a dialog's file-type filter. `extensions` are without the dot.
61
+ struct FileFilter {
62
+ std::string name;
63
+ std::vector<std::string> extensions;
64
+ };
65
+
66
+ struct FileDialogRequest {
67
+ enum class Kind {
68
+ // One or more existing files.
69
+ OpenFile,
70
+ // A path to write to, existing or not. The only kind that asks about
71
+ // overwriting, which every platform does for itself.
72
+ SaveFile,
73
+ // A directory.
74
+ OpenFolder,
75
+ };
76
+
77
+ Kind kind{Kind::OpenFile};
78
+ std::string title;
79
+ // Where to start, and for a save, what to call it. A directory for the two
80
+ // open kinds; a file name, optionally with a directory, for a save.
81
+ std::string defaultPath;
82
+ // What the accepting button says. Empty means the system's own word, which
83
+ // is almost always the right one.
84
+ std::string confirmLabel;
85
+ // OpenFile only. Ignored by the other two, because no desktop has a
86
+ // multiple-selection save.
87
+ bool multiple{false};
88
+ std::vector<FileFilter> filters;
89
+ };
90
+
91
+ // Shows a file dialog and calls `onDone` with what was chosen, or with
92
+ // `canceled` and nothing.
93
+ //
94
+ // Must not block, for the same reason `showAlert` must not: this is called from
95
+ // the JavaScript thread and a modal run loop there would deadlock the runtime.
96
+ // Implementations marshal to the main thread and return at once.
97
+ //
98
+ // Paths are absolute, and are whatever the platform calls a path -- a Windows
99
+ // one has backslashes in it. Nothing here normalises them: an app passes them
100
+ // straight back to `fetch`, to a native module, or to the same dialog next
101
+ // time, and a "tidied" path is one the system may no longer recognise.
102
+ using FileDialogCallback =
103
+ std::function<void(bool canceled, const std::vector<std::string> &paths)>;
104
+ void showFileDialog(const FileDialogRequest &request, FileDialogCallback onDone);
105
+
106
+ // --- Menus --------------------------------------------------------------------
107
+
108
+ // One entry in a popup menu. A separator is an item with an empty label, which
109
+ // is how GMenu, NSMenu and an HMENU each spell it too.
110
+ struct MenuEntry {
111
+ std::string label;
112
+ // Shown greyed and not choosable. A menu of only disabled items is still a
113
+ // menu, which is what makes this better than leaving the entry out.
114
+ bool enabled{true};
115
+ // Drawn beside the label -- "Cmd+R", "Ctrl+R". Decoration only: nothing here
116
+ // binds a key, because the shortcut that opened the menu and the shortcuts
117
+ // inside it are answered in different places on all three desktops.
118
+ std::string shortcut;
119
+
120
+ static MenuEntry separator() {
121
+ return MenuEntry{.label = {}, .enabled = false, .shortcut = {}};
122
+ }
123
+
124
+ bool isSeparator() const {
125
+ return label.empty();
126
+ }
127
+ };
128
+
129
+ struct MenuRequest {
130
+ std::vector<MenuEntry> entries;
131
+ // Where to put it, in the window's coordinates. A negative point means "wherever
132
+ // the pointer is", which is what a menu opened from the keyboard wants.
133
+ double x{-1.0};
134
+ double y{-1.0};
135
+ };
136
+
137
+ // Shows a popup menu and calls `onChosen` with the index of the entry picked,
138
+ // or -1 when it was dismissed. Indexes count separators, so they line up with
139
+ // the vector that was passed in.
140
+ //
141
+ // Must not block, for the same reason `showAlert` must not: this can be called
142
+ // from the JavaScript thread, and a menu's own run loop there would deadlock
143
+ // the runtime. Implementations marshal to the main thread and return at once.
144
+ using MenuCallback = std::function<void(int index)>;
145
+ void showMenu(const MenuRequest &request, MenuCallback onChosen);
146
+
147
+ // --- Sharing ------------------------------------------------------------------
148
+
149
+ // What an app asked to share. React Native's `Share.share()` takes `message`,
150
+ // `url` and `title`, and marks each as belonging to one platform or the other;
151
+ // a desktop has no reason to honour that split, so all three arrive and each
152
+ // implementation uses what it can.
153
+ struct ShareRequest {
154
+ std::string message;
155
+ std::string url;
156
+ std::string title;
157
+ // `options.dialogTitle`, which names the picker on the platforms that show
158
+ // one they did not draw themselves.
159
+ std::string dialogTitle;
160
+ };
161
+
162
+ // What became of it. React Native's promise resolves with `sharedAction` or
163
+ // `dismissedAction` and rejects on anything else, so these are the three
164
+ // answers it can carry and no more.
165
+ enum class ShareOutcome { Shared, Dismissed, Failed };
166
+
167
+ // `message` is meaningful only for Failed, and becomes the rejection's reason.
168
+ using ShareCallback = std::function<void(ShareOutcome outcome, const std::string &message)>;
169
+
170
+ // Puts the content in front of the user and reports what they did with it.
171
+ //
172
+ // Must not block, for the same reason `showAlert` must not: it is called from
173
+ // the JavaScript thread and a modal run loop there would deadlock the runtime.
174
+ // Implementations marshal to the main thread and return at once, and the
175
+ // callback comes later -- possibly much later, because a share sheet is on
176
+ // screen until a person does something with it.
177
+ //
178
+ // Only macOS has a share service of its own. The other two go through
179
+ // core/ShareFallback.h, which builds a picker from a clipboard and a mail
180
+ // client; see its header for why that is the honest answer rather than a
181
+ // rejection.
182
+ void shareContent(const ShareRequest &request, ShareCallback onDone);
183
+
184
+ // Runs `work` on the UI thread after `milliseconds`, once.
185
+ //
186
+ // Every gesture recogniser needs this and nothing else does yet: a long press
187
+ // activates because nothing happened for half a second, and a double tap fails
188
+ // because a second tap did not arrive. Both are "wake me if this is still true
189
+ // later", which cannot be expressed by reacting to input alone.
190
+ //
191
+ // The callback runs on the thread that draws -- the same one input arrives on
192
+ // -- so what it touches needs no lock. There is no way to cancel: a recogniser
193
+ // that has moved on checks its own state when it wakes, which is simpler than
194
+ // owning a handle and correct even when the work has already started.
195
+ void postDelayed(double milliseconds, std::function<void()> work);
196
+
197
+ // Runs `work` on the UI thread, soon, in the order posted.
198
+ //
199
+ // The gesture registry is UI-thread state -- input arrives there and the
200
+ // recognisers run there -- but the module that configures it is called from
201
+ // JavaScript. Rather than lock the registry, its callers hop threads, which is
202
+ // the same rule the mounting managers keep and assert.
203
+ void postToUiThread(std::function<void()> work);
204
+
205
+ // Whether this is the thread that draws.
206
+ //
207
+ // Fabric dispatches an event from whichever thread produced it -- a touch from
208
+ // the UI thread, a layout event from the JavaScript thread -- and anything that
209
+ // answers by touching a worklet runtime has to know which it is on. That is the
210
+ // one caller today; see core/ReanimatedModule.cpp.
211
+ bool isUiThread();
212
+
213
+ } // namespace basalt
@@ -0,0 +1,63 @@
1
+ // Which mouse button, and what the three desktops do about it.
2
+ //
3
+ // Header-only and shared, because the numbers are the thing three copies drift
4
+ // on: each toolkit numbers its buttons differently, W3C numbers them a third
5
+ // way, and React Native's `PointerEvent` carries W3C's.
6
+ //
7
+ // ## Why this exists at all
8
+ //
9
+ // React Native's *touch* model has no concept of which button -- a phone has
10
+ // one finger and no buttons -- so until now every host forwarded every click as
11
+ // a touch. That was three different wrongs. GTK set its click gesture to button
12
+ // 0, meaning all of them, and AppKit forwarded `rightMouseDown:` the same as
13
+ // `mouseDown:`, so on both a right-click *activated* whatever it landed on: a
14
+ // `<Pressable>` fired its `onPress` from the wrong button. Windows handled only
15
+ // WM_LBUTTONDOWN, so a right-click there did nothing whatsoever.
16
+ //
17
+ // What a desktop expects is neither. A secondary click is not a press -- the web
18
+ // does not fire `click` for one, and no desktop toolkit treats it as an
19
+ // activation -- it is a request for a context menu. So a secondary or middle
20
+ // click now produces a pointer event and no touch, which is what lets an app
21
+ // answer it without every `<Pressable>` on the screen answering first.
22
+
23
+ #pragma once
24
+
25
+ #include <cstdint>
26
+
27
+ namespace basalt {
28
+
29
+ // W3C's numbering, which is what `PointerEvent::button` carries. Not the
30
+ // toolkits': GTK counts from 1, AppKit has a separate selector per button, and
31
+ // Windows has a separate message.
32
+ enum class PointerButton : int {
33
+ Primary = 0,
34
+ Middle = 1,
35
+ Secondary = 2,
36
+ };
37
+
38
+ // Whether this button presses things.
39
+ //
40
+ // The whole question in one place. Only the primary button drives React
41
+ // Native's touch model -- responder negotiation, `onPress`, a gesture handler
42
+ // claiming the pointer -- because that model has no way to say which button it
43
+ // was, and a right-click that pressed things is the bug this exists to stop.
44
+ inline bool isPressButton(PointerButton button) {
45
+ return button == PointerButton::Primary;
46
+ }
47
+
48
+ // `PointerEvent::buttons`, the mask of what is held *during* the event. A
49
+ // different number from `button` in the same event, which is exactly the sort
50
+ // of thing worth writing down once: primary is 1, secondary is 2, middle is 4.
51
+ inline std::uint32_t buttonsMaskFor(PointerButton button) {
52
+ switch (button) {
53
+ case PointerButton::Primary:
54
+ return 1;
55
+ case PointerButton::Middle:
56
+ return 4;
57
+ case PointerButton::Secondary:
58
+ return 2;
59
+ }
60
+ return 0;
61
+ }
62
+
63
+ } // namespace basalt
@@ -0,0 +1,57 @@
1
+ #include "PullToRefresh.h"
2
+
3
+ namespace basalt {
4
+
5
+ using facebook::react::Tag;
6
+
7
+ void PullToRefreshTracker::attach(Tag scrollTag, Tag controlTag) {
8
+ if (scrollTag == 0 || controlTag == 0) {
9
+ return;
10
+ }
11
+ byScroll_[scrollTag].control = controlTag;
12
+ scrollByControl_[controlTag] = scrollTag;
13
+ }
14
+
15
+ void PullToRefreshTracker::forget(Tag tag) {
16
+ if (const auto asControl = scrollByControl_.find(tag); asControl != scrollByControl_.end()) {
17
+ byScroll_.erase(asControl->second);
18
+ scrollByControl_.erase(asControl);
19
+ return;
20
+ }
21
+ if (const auto asScroll = byScroll_.find(tag); asScroll != byScroll_.end()) {
22
+ scrollByControl_.erase(asScroll->second.control);
23
+ byScroll_.erase(asScroll);
24
+ }
25
+ }
26
+
27
+ Tag PullToRefreshTracker::controlFor(Tag scrollTag) const {
28
+ const auto found = byScroll_.find(scrollTag);
29
+ return found != byScroll_.end() ? found->second.control : 0;
30
+ }
31
+
32
+ bool PullToRefreshTracker::pull(Tag scrollTag, double amount) {
33
+ const auto found = byScroll_.find(scrollTag);
34
+ if (found == byScroll_.end()) {
35
+ return false;
36
+ }
37
+ Entry &entry = found->second;
38
+ if (amount > 0.0) {
39
+ entry.pulled += amount;
40
+ }
41
+ if (entry.fired || entry.pulled < kPullToRefreshThreshold) {
42
+ return false;
43
+ }
44
+ entry.fired = true;
45
+ return true;
46
+ }
47
+
48
+ void PullToRefreshTracker::release(Tag scrollTag) {
49
+ const auto found = byScroll_.find(scrollTag);
50
+ if (found == byScroll_.end()) {
51
+ return;
52
+ }
53
+ found->second.pulled = 0.0;
54
+ found->second.fired = false;
55
+ }
56
+
57
+ } // namespace basalt
@@ -0,0 +1,73 @@
1
+ // The pull half of <RefreshControl>.
2
+ //
3
+ // A desktop scroll view has no rubber band. There is nothing to drag past the
4
+ // top, no elastic to stretch, and no released-at-a-distance moment to fire on
5
+ // -- which is why React Native's own pull-to-refresh exists on phones and not
6
+ // here. What a desktop does have is a wheel that keeps reporting upward scroll
7
+ // after the offset has already reached zero, and that is the same gesture in
8
+ // every way that matters: the person is asking for something above the top of
9
+ // the list.
10
+ //
11
+ // So this counts that. The scroll view clamps its offset as it always has --
12
+ // nothing here moves anything -- and hands over how far past the top the
13
+ // gesture asked to go. Once that passes the threshold, `onRefresh` fires once,
14
+ // and not again until the gesture stops.
15
+ //
16
+ // Portable for the usual reason: the counting is identical on three desktops
17
+ // and the wheel plumbing is not. It also makes the one part that is easy to get
18
+ // wrong -- firing repeatedly while somebody keeps scrolling -- testable without
19
+ // a mouse.
20
+
21
+ #pragma once
22
+
23
+ #include "DesktopControls.h"
24
+
25
+ #include <react/renderer/core/ReactPrimitives.h>
26
+
27
+ #include <unordered_map>
28
+
29
+ namespace basalt {
30
+
31
+ class PullToRefreshTracker {
32
+ public:
33
+ // Says that `controlTag` is the <RefreshControl> belonging to `scrollTag`.
34
+ // Called by the mounting manager when a PullToRefreshView is parented, which
35
+ // is the only place the relationship is visible.
36
+ void attach(facebook::react::Tag scrollTag, facebook::react::Tag controlTag);
37
+
38
+ // Drops whatever `tag` was, whether it was a scroll view or a control.
39
+ void forget(facebook::react::Tag tag);
40
+
41
+ // The refresh control for a scroll view, or 0 for a scroll view with none.
42
+ facebook::react::Tag controlFor(facebook::react::Tag scrollTag) const;
43
+
44
+ // How far past the top this gesture has asked to go, accumulated. `amount`
45
+ // is in points and positive; a downward scroll or any scroll that actually
46
+ // moved the view calls `release` instead.
47
+ //
48
+ // Returns true exactly once per gesture: on the step that crosses the
49
+ // threshold. A scroll view with no refresh control always returns false, so
50
+ // the caller needs no separate check.
51
+ bool pull(facebook::react::Tag scrollTag, double amount);
52
+
53
+ // The gesture ended, or moved the scroll view off the top. Re-arms the pull.
54
+ void release(facebook::react::Tag scrollTag);
55
+
56
+ private:
57
+ struct Entry {
58
+ facebook::react::Tag control{0};
59
+ double pulled{0.0};
60
+ // Whether this gesture has already fired. Without it a wheel held down
61
+ // fires `onRefresh` sixty times a second, and React Native's contract is
62
+ // one call per pull.
63
+ bool fired{false};
64
+ };
65
+
66
+ std::unordered_map<facebook::react::Tag, Entry> byScroll_;
67
+ // The other direction, so `forget` works when a control is deleted and its
68
+ // scroll view is not -- which is what unmounting a <RefreshControl> looks
69
+ // like.
70
+ std::unordered_map<facebook::react::Tag, facebook::react::Tag> scrollByControl_;
71
+ };
72
+
73
+ } // namespace basalt
@@ -0,0 +1,47 @@
1
+ // What react-native-reanimated's C++ needs on a platform that is neither
2
+ // Android nor Apple.
3
+ //
4
+ // Force-included ahead of Reanimated's own sources; see cmake/Reanimated.cmake.
5
+ //
6
+ // Reanimated calls `Common/cpp` its portable half and it very nearly is -- the
7
+ // animation clock, the shadow-tree cloning, the CSS engine and the registries
8
+ // are all platform-independent. But about ninety `#ifdef ANDROID` /
9
+ // `#ifdef __APPLE__` branches run through it, and a few of them choose a *type*
10
+ // rather than an implementation:
11
+ //
12
+ // #ifdef ANDROID
13
+ // using SynchronouslyUpdateUIPropsFunction = ...
14
+ // #elif __APPLE__
15
+ // using SynchronouslyUpdateUIPropsFunction = ...
16
+ // #endif
17
+ //
18
+ // On a third platform that alias is never declared, and `PlatformDepMethodsHolder`
19
+ // -- which has a member of that type unconditionally -- does not compile.
20
+ //
21
+ // Declaring it here first is enough: the `#elif` chain then skips a definition
22
+ // that already exists, and everything downstream sees the type it expected.
23
+ // Nothing is patched and nothing is vendored, which is the same rule the rest
24
+ // of this project keeps.
25
+ //
26
+ // The Apple shape is the one chosen, for the reason it is chosen everywhere
27
+ // else here: it takes a tag and a dynamic, which is what a desktop mounting
28
+ // manager can act on, while Android's takes two parallel arrays built for JNI.
29
+ //
30
+ // This file is only reached on a build that is neither Android nor Apple, which
31
+ // today means Linux and, later, Windows. On macOS it compiles to nothing.
32
+
33
+ #pragma once
34
+
35
+ #if !defined(ANDROID) && !defined(__APPLE__)
36
+
37
+ #include <folly/dynamic.h>
38
+
39
+ #include <functional>
40
+
41
+ namespace reanimated {
42
+
43
+ using SynchronouslyUpdateUIPropsFunction = std::function<void(const int, const folly::dynamic &)>;
44
+
45
+ } // namespace reanimated
46
+
47
+ #endif