@apollohg/react-native-rich-text-editor 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (494) hide show
  1. package/LICENSE +160 -0
  2. package/README.md +259 -0
  3. package/RUST-STANDARD-LIBRARY-NOTICES.html +8266 -0
  4. package/ReactNativeProseEditor.podspec +59 -0
  5. package/THIRD_PARTY_NOTICES.md +31155 -0
  6. package/android/build.gradle +188 -0
  7. package/android/consumer-rules.pro +18 -0
  8. package/android/expo/build.gradle +17 -0
  9. package/android/src/debug/java/com/apollohg/editor/viewer/PreparedProseDrawInstrumentation.kt +7 -0
  10. package/android/src/main/assets/editor-icons/MaterialIcons.json +2236 -0
  11. package/android/src/main/assets/editor-icons/MaterialIcons.ttf +0 -0
  12. package/android/src/main/java/com/apollohg/editor/AndroidApiCompat.kt +19 -0
  13. package/android/src/main/java/com/apollohg/editor/AndroidCollaborationTransport.kt +860 -0
  14. package/android/src/main/java/com/apollohg/editor/CaretGeometry.kt +91 -0
  15. package/android/src/main/java/com/apollohg/editor/CodeHighlighting.kt +141 -0
  16. package/android/src/main/java/com/apollohg/editor/DecodedBitmapBudget.kt +250 -0
  17. package/android/src/main/java/com/apollohg/editor/EditorAddons.kt +133 -0
  18. package/android/src/main/java/com/apollohg/editor/EditorBlockSpacing.kt +51 -0
  19. package/android/src/main/java/com/apollohg/editor/EditorBoxDrawable.kt +16 -0
  20. package/android/src/main/java/com/apollohg/editor/EditorBoxDrawing.kt +234 -0
  21. package/android/src/main/java/com/apollohg/editor/EditorCheckboxSpan.kt +87 -0
  22. package/android/src/main/java/com/apollohg/editor/EditorCodeHighlighting.kt +120 -0
  23. package/android/src/main/java/com/apollohg/editor/EditorDecorationLayer.java +18 -0
  24. package/android/src/main/java/com/apollohg/editor/EditorDocumentLayout.kt +626 -0
  25. package/android/src/main/java/com/apollohg/editor/EditorEditText.kt +1042 -0
  26. package/android/src/main/java/com/apollohg/editor/EditorEditTextAnnotations.kt +191 -0
  27. package/android/src/main/java/com/apollohg/editor/EditorEditTextCaret.kt +100 -0
  28. package/android/src/main/java/com/apollohg/editor/EditorEditTextClipboard.kt +101 -0
  29. package/android/src/main/java/com/apollohg/editor/EditorEditTextComposition.kt +220 -0
  30. package/android/src/main/java/com/apollohg/editor/EditorEditTextConfiguration.kt +316 -0
  31. package/android/src/main/java/com/apollohg/editor/EditorEditTextCorrection.kt +303 -0
  32. package/android/src/main/java/com/apollohg/editor/EditorEditTextDeferredUpdates.kt +327 -0
  33. package/android/src/main/java/com/apollohg/editor/EditorEditTextDeletion.kt +258 -0
  34. package/android/src/main/java/com/apollohg/editor/EditorEditTextDiagnostics.kt +83 -0
  35. package/android/src/main/java/com/apollohg/editor/EditorEditTextDragDrop.kt +67 -0
  36. package/android/src/main/java/com/apollohg/editor/EditorEditTextExternalComposition.kt +357 -0
  37. package/android/src/main/java/com/apollohg/editor/EditorEditTextHardwareInput.kt +277 -0
  38. package/android/src/main/java/com/apollohg/editor/EditorEditTextImages.kt +280 -0
  39. package/android/src/main/java/com/apollohg/editor/EditorEditTextInputLifecycle.kt +183 -0
  40. package/android/src/main/java/com/apollohg/editor/EditorEditTextInputPreparation.kt +79 -0
  41. package/android/src/main/java/com/apollohg/editor/EditorEditTextInputTraits.kt +384 -0
  42. package/android/src/main/java/com/apollohg/editor/EditorEditTextLayout.kt +100 -0
  43. package/android/src/main/java/com/apollohg/editor/EditorEditTextNativeMutation.kt +243 -0
  44. package/android/src/main/java/com/apollohg/editor/EditorEditTextPlaceholder.kt +154 -0
  45. package/android/src/main/java/com/apollohg/editor/EditorEditTextRenderPatch.kt +347 -0
  46. package/android/src/main/java/com/apollohg/editor/EditorEditTextRendering.kt +313 -0
  47. package/android/src/main/java/com/apollohg/editor/EditorEditTextRustCommands.kt +281 -0
  48. package/android/src/main/java/com/apollohg/editor/EditorEditTextSelection.kt +352 -0
  49. package/android/src/main/java/com/apollohg/editor/EditorEditTextState.kt +113 -0
  50. package/android/src/main/java/com/apollohg/editor/EditorEditTextTaskMarkers.kt +92 -0
  51. package/android/src/main/java/com/apollohg/editor/EditorEditTextTextCommit.kt +327 -0
  52. package/android/src/main/java/com/apollohg/editor/EditorEditTextToolbar.kt +84 -0
  53. package/android/src/main/java/com/apollohg/editor/EditorEditTextUpdates.kt +245 -0
  54. package/android/src/main/java/com/apollohg/editor/EditorGlyphHeightCursorDrawable.kt +42 -0
  55. package/android/src/main/java/com/apollohg/editor/EditorHeightBehavior.kt +13 -0
  56. package/android/src/main/java/com/apollohg/editor/EditorInputConnection.kt +923 -0
  57. package/android/src/main/java/com/apollohg/editor/EditorInputCoordinates.kt +191 -0
  58. package/android/src/main/java/com/apollohg/editor/EditorInputCorrection.kt +107 -0
  59. package/android/src/main/java/com/apollohg/editor/EditorInputCursorGeometry.kt +128 -0
  60. package/android/src/main/java/com/apollohg/editor/EditorInputSnapshots.kt +134 -0
  61. package/android/src/main/java/com/apollohg/editor/EditorInputSurroundingDeletion.kt +321 -0
  62. package/android/src/main/java/com/apollohg/editor/EditorKeyboardToolbarView.kt +851 -0
  63. package/android/src/main/java/com/apollohg/editor/EditorMentionStyle.kt +192 -0
  64. package/android/src/main/java/com/apollohg/editor/EditorReconciliationWatcher.kt +46 -0
  65. package/android/src/main/java/com/apollohg/editor/EditorStyleSheet.kt +303 -0
  66. package/android/src/main/java/com/apollohg/editor/EditorStyleSheetSpans.kt +253 -0
  67. package/android/src/main/java/com/apollohg/editor/EditorSurfaceInputConnection.kt +67 -0
  68. package/android/src/main/java/com/apollohg/editor/EditorTextDecorationDrawing.kt +143 -0
  69. package/android/src/main/java/com/apollohg/editor/EditorTextSurface.kt +712 -0
  70. package/android/src/main/java/com/apollohg/editor/EditorTextSurfaceDragDrop.kt +94 -0
  71. package/android/src/main/java/com/apollohg/editor/EditorTextSurfaceInteraction.kt +708 -0
  72. package/android/src/main/java/com/apollohg/editor/EditorTheme.kt +650 -0
  73. package/android/src/main/java/com/apollohg/editor/EditorV2Adapter.kt +912 -0
  74. package/android/src/main/java/com/apollohg/editor/EditorV2AdapterMutations.kt +402 -0
  75. package/android/src/main/java/com/apollohg/editor/EditorV2AdapterRendering.kt +123 -0
  76. package/android/src/main/java/com/apollohg/editor/EditorV2AdapterSelection.kt +203 -0
  77. package/android/src/main/java/com/apollohg/editor/EditorV2Backend.kt +120 -0
  78. package/android/src/main/java/com/apollohg/editor/EditorV2Driver.kt +87 -0
  79. package/android/src/main/java/com/apollohg/editor/EditorV2Registry.kt +97 -0
  80. package/android/src/main/java/com/apollohg/editor/EditorV2RenderValidation.kt +409 -0
  81. package/android/src/main/java/com/apollohg/editor/ExpoAutoGrowStyleSizePublisher.kt +34 -0
  82. package/android/src/main/java/com/apollohg/editor/ImageResizeOverlayView.kt +266 -0
  83. package/android/src/main/java/com/apollohg/editor/ImeTextCoordinateMapper.kt +102 -0
  84. package/android/src/main/java/com/apollohg/editor/KeyboardToolbarImeAnimationController.kt +101 -0
  85. package/android/src/main/java/com/apollohg/editor/MentionSuggestionChipView.kt +234 -0
  86. package/android/src/main/java/com/apollohg/editor/NativeCollaborationTransportRegistry.kt +493 -0
  87. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoView.kt +813 -0
  88. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewAtoms.kt +68 -0
  89. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewBinding.kt +126 -0
  90. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewDiagnostics.kt +208 -0
  91. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewErrors.kt +146 -0
  92. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewEvents.kt +150 -0
  93. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewExternalComposition.kt +39 -0
  94. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewFocus.kt +176 -0
  95. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewLifecycle.kt +302 -0
  96. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewMentions.kt +259 -0
  97. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewNativeActions.kt +179 -0
  98. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewOutsideTap.kt +214 -0
  99. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewPendingUpdates.kt +376 -0
  100. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewProperties.kt +234 -0
  101. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewPropertyRetries.kt +197 -0
  102. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewToolbar.kt +285 -0
  103. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewTypes.kt +28 -0
  104. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewUpdates.kt +271 -0
  105. package/android/src/main/java/com/apollohg/editor/NativeEditorModule.kt +687 -0
  106. package/android/src/main/java/com/apollohg/editor/NativeEditorOutsideTapDispatcher.kt +380 -0
  107. package/android/src/main/java/com/apollohg/editor/NativeEditorV2Numbers.kt +45 -0
  108. package/android/src/main/java/com/apollohg/editor/NativeEditorViewRegistry.kt +372 -0
  109. package/android/src/main/java/com/apollohg/editor/NativeImagePipeline.kt +22 -0
  110. package/android/src/main/java/com/apollohg/editor/NativeToolbar.kt +193 -0
  111. package/android/src/main/java/com/apollohg/editor/NativeToolbarIcons.kt +177 -0
  112. package/android/src/main/java/com/apollohg/editor/NativeToolbarItem.kt +274 -0
  113. package/android/src/main/java/com/apollohg/editor/OkHttpCollaborationSocket.kt +102 -0
  114. package/android/src/main/java/com/apollohg/editor/OrderedListMarkerFormatter.kt +130 -0
  115. package/android/src/main/java/com/apollohg/editor/PointerTransparentView.java +18 -0
  116. package/android/src/main/java/com/apollohg/editor/PositionBridge.kt +128 -0
  117. package/android/src/main/java/com/apollohg/editor/ProseViewerView.kt +854 -0
  118. package/android/src/main/java/com/apollohg/editor/RemoteSelectionOverlayView.kt +314 -0
  119. package/android/src/main/java/com/apollohg/editor/RenderBlockSpans.kt +314 -0
  120. package/android/src/main/java/com/apollohg/editor/RenderBridge.kt +224 -0
  121. package/android/src/main/java/com/apollohg/editor/RenderBridgeBlockStyles.kt +407 -0
  122. package/android/src/main/java/com/apollohg/editor/RenderBridgeElements.kt +544 -0
  123. package/android/src/main/java/com/apollohg/editor/RenderBridgeInlineAndAtoms.kt +631 -0
  124. package/android/src/main/java/com/apollohg/editor/RenderBridgeParagraphs.kt +215 -0
  125. package/android/src/main/java/com/apollohg/editor/RenderImageDecoder.kt +748 -0
  126. package/android/src/main/java/com/apollohg/editor/RenderImageLoader.kt +900 -0
  127. package/android/src/main/java/com/apollohg/editor/RenderLayoutConstants.kt +117 -0
  128. package/android/src/main/java/com/apollohg/editor/RenderMediaSpans.kt +337 -0
  129. package/android/src/main/java/com/apollohg/editor/RenderParagraphSpans.kt +182 -0
  130. package/android/src/main/java/com/apollohg/editor/RichTextEditorView.kt +951 -0
  131. package/android/src/main/java/com/apollohg/editor/SharedNativeImagePipeline.kt +78 -0
  132. package/android/src/main/java/com/apollohg/editor/UniffiEditorV2Backend.kt +261 -0
  133. package/android/src/main/java/com/apollohg/editor/viewer/AndroidProseLayoutEngine.kt +1656 -0
  134. package/android/src/main/java/com/apollohg/editor/viewer/FabricAttachmentSidecars.kt +80 -0
  135. package/android/src/main/java/com/apollohg/editor/viewer/FabricLeaseHandleBridge.kt +59 -0
  136. package/android/src/main/java/com/apollohg/editor/viewer/FallbackSelectionGeometry.kt +450 -0
  137. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseDrawingView.kt +678 -0
  138. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseInstrumentation.kt +608 -0
  139. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayout.kt +186 -0
  140. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayoutCache.kt +393 -0
  141. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseLayoutRegistry.kt +828 -0
  142. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseTheme.kt +316 -0
  143. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseViewerManager.kt +900 -0
  144. package/android/src/main/java/com/apollohg/editor/viewer/PreparedProseViewerPackage.kt +16 -0
  145. package/android/src/main/java/com/apollohg/editor/viewer/PreparedViewerAtoms.kt +89 -0
  146. package/android/src/main/java/com/apollohg/editor/viewer/ViewerCodeHighlighting.kt +91 -0
  147. package/android/src/main/java/com/apollohg/editor/viewer/ViewerDocument.kt +453 -0
  148. package/android/src/main/java/com/apollohg/editor/viewer/ViewerFontEnvironment.kt +282 -0
  149. package/android/src/main/java/com/apollohg/editor/viewer/ViewerImagePipeline.kt +460 -0
  150. package/android/src/main/jni/CMakeLists.txt +85 -0
  151. package/android/src/main/jni/PreparedProseViewerMeasurementsManager.cpp +334 -0
  152. package/android/src/main/jni/ReactNativeProseEditorSpec.h +17 -0
  153. package/android/src/main/jni/reactnativeproseeditor.h +6 -0
  154. package/android/src/main/res/values/attrs.xml +6 -0
  155. package/android/src/release/java/com/apollohg/editor/viewer/PreparedProseDrawInstrumentation.kt +9 -0
  156. package/app.plugin.js +62 -0
  157. package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseMeasurementsManager.h +62 -0
  158. package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerComponentDescriptor.h +30 -0
  159. package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerShadowNode.cpp +192 -0
  160. package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerShadowNode.h +46 -0
  161. package/common/cpp/react/renderer/components/PreparedProseViewer/PreparedProseViewerState.h +145 -0
  162. package/dist/AtomHost.d.ts +17 -0
  163. package/dist/AtomHost.js +135 -0
  164. package/dist/DefaultAtomChip.d.ts +2 -0
  165. package/dist/DefaultAtomChip.js +22 -0
  166. package/dist/EditorAddon.d.ts +32 -0
  167. package/dist/EditorAddon.js +29 -0
  168. package/dist/EditorAddonNormalization.d.ts +6 -0
  169. package/dist/EditorAddonNormalization.js +48 -0
  170. package/dist/EditorMentionThemeNormalization.d.ts +8 -0
  171. package/dist/EditorMentionThemeNormalization.js +22 -0
  172. package/dist/EditorMentionThemeValidation.d.ts +12 -0
  173. package/dist/EditorMentionThemeValidation.js +95 -0
  174. package/dist/EditorStyleSheet.d.ts +4 -0
  175. package/dist/EditorStyleSheet.js +10 -0
  176. package/dist/EditorStyleSheetNormalization.d.ts +3 -0
  177. package/dist/EditorStyleSheetNormalization.js +226 -0
  178. package/dist/EditorStyleSheetTypes.d.ts +151 -0
  179. package/dist/EditorStyleSheetTypes.js +2 -0
  180. package/dist/EditorTheme.d.ts +117 -0
  181. package/dist/EditorTheme.js +41 -0
  182. package/dist/EditorToolbar.d.ts +4 -0
  183. package/dist/EditorToolbar.js +17 -0
  184. package/dist/EditorToolbarComponent.d.ts +13 -0
  185. package/dist/EditorToolbarComponent.js +24 -0
  186. package/dist/EditorToolbarItems.d.ts +9 -0
  187. package/dist/EditorToolbarItems.js +58 -0
  188. package/dist/EditorToolbarRegistry.d.ts +59 -0
  189. package/dist/EditorToolbarRegistry.js +175 -0
  190. package/dist/EditorToolbarTypes.d.ts +273 -0
  191. package/dist/EditorToolbarTypes.js +2 -0
  192. package/dist/EditorToolbarVisuals.d.ts +154 -0
  193. package/dist/EditorToolbarVisuals.js +228 -0
  194. package/dist/EditorUpdateRevision.d.ts +8 -0
  195. package/dist/EditorUpdateRevision.js +22 -0
  196. package/dist/ExternalTextComposition.d.ts +45 -0
  197. package/dist/ExternalTextComposition.js +537 -0
  198. package/dist/ImageLoadingPolicy.d.ts +54 -0
  199. package/dist/ImageLoadingPolicy.js +60 -0
  200. package/dist/NativeEditorBoundaryError.d.ts +111 -0
  201. package/dist/NativeEditorBoundaryError.js +268 -0
  202. package/dist/NativeEditorBridge.d.ts +9 -0
  203. package/dist/NativeEditorBridge.js +37 -0
  204. package/dist/NativeEditorCollaborationTransport.d.ts +154 -0
  205. package/dist/NativeEditorCollaborationTransport.js +275 -0
  206. package/dist/NativeEditorCreateConfig.d.ts +16 -0
  207. package/dist/NativeEditorCreateConfig.js +249 -0
  208. package/dist/NativeEditorCreateJson.d.ts +76 -0
  209. package/dist/NativeEditorCreateJson.js +474 -0
  210. package/dist/NativeEditorCreateValidation.d.ts +32 -0
  211. package/dist/NativeEditorCreateValidation.js +150 -0
  212. package/dist/NativeEditorDocumentBridge.d.ts +72 -0
  213. package/dist/NativeEditorDocumentBridge.js +305 -0
  214. package/dist/NativeEditorDocumentHandle.d.ts +70 -0
  215. package/dist/NativeEditorDocumentHandle.js +89 -0
  216. package/dist/NativeEditorLocalAwareness.d.ts +34 -0
  217. package/dist/NativeEditorLocalAwareness.js +153 -0
  218. package/dist/NativeEditorNativeModule.d.ts +48 -0
  219. package/dist/NativeEditorNativeModule.js +34 -0
  220. package/dist/NativeEditorRenderNormalization.d.ts +22 -0
  221. package/dist/NativeEditorRenderNormalization.js +274 -0
  222. package/dist/NativeEditorResultNormalization.d.ts +108 -0
  223. package/dist/NativeEditorResultNormalization.js +400 -0
  224. package/dist/NativeEditorTypes.d.ts +318 -0
  225. package/dist/NativeEditorTypes.js +15 -0
  226. package/dist/NativeEditorV2Decimal.d.ts +5 -0
  227. package/dist/NativeEditorV2Decimal.js +18 -0
  228. package/dist/NativeProseViewer.d.ts +122 -0
  229. package/dist/NativeProseViewer.js +130 -0
  230. package/dist/NativeRichTextEditor.d.ts +3 -0
  231. package/dist/NativeRichTextEditor.js +6 -0
  232. package/dist/ResourceLimits.d.ts +100 -0
  233. package/dist/ResourceLimits.js +80 -0
  234. package/dist/RichTextEditor.d.ts +4 -0
  235. package/dist/RichTextEditor.js +25 -0
  236. package/dist/RichTextEditorNativeTypes.d.ts +122 -0
  237. package/dist/RichTextEditorNativeTypes.js +2 -0
  238. package/dist/RichTextEditorNativeView.d.ts +12 -0
  239. package/dist/RichTextEditorNativeView.js +15 -0
  240. package/dist/RichTextEditorSerialization.d.ts +53 -0
  241. package/dist/RichTextEditorSerialization.js +283 -0
  242. package/dist/RichTextEditorTypes.d.ts +281 -0
  243. package/dist/RichTextEditorTypes.js +2 -0
  244. package/dist/ViewerConfiguration.d.ts +22 -0
  245. package/dist/ViewerConfiguration.js +6 -0
  246. package/dist/YjsCollaboration.d.ts +146 -0
  247. package/dist/YjsCollaboration.js +496 -0
  248. package/dist/addons.d.ts +193 -0
  249. package/dist/addons.js +122 -0
  250. package/dist/atomConstants.d.ts +3 -0
  251. package/dist/atomConstants.js +6 -0
  252. package/dist/atomInstances.d.ts +35 -0
  253. package/dist/atomInstances.js +79 -0
  254. package/dist/atomPolicy.d.ts +4 -0
  255. package/dist/atomPolicy.js +47 -0
  256. package/dist/atomUpdates.d.ts +2 -0
  257. package/dist/atomUpdates.js +38 -0
  258. package/dist/atoms.d.ts +92 -0
  259. package/dist/atoms.js +222 -0
  260. package/dist/attributeValidation.d.ts +4 -0
  261. package/dist/attributeValidation.js +97 -0
  262. package/dist/contentExpression.d.ts +6 -0
  263. package/dist/contentExpression.js +335 -0
  264. package/dist/index.d.ts +21 -0
  265. package/dist/index.js +78 -0
  266. package/dist/listMarkers.d.ts +15 -0
  267. package/dist/listMarkers.js +21 -0
  268. package/dist/schemaDefinition.d.ts +143 -0
  269. package/dist/schemaDefinition.js +206 -0
  270. package/dist/schemaDocument.d.ts +17 -0
  271. package/dist/schemaDocument.js +69 -0
  272. package/dist/schemaDocumentConstruction.d.ts +5 -0
  273. package/dist/schemaDocumentConstruction.js +125 -0
  274. package/dist/schemaNormalization.d.ts +29 -0
  275. package/dist/schemaNormalization.js +313 -0
  276. package/dist/schemaPresets.d.ts +68 -0
  277. package/dist/schemaPresets.js +198 -0
  278. package/dist/schemaResolution.d.ts +9 -0
  279. package/dist/schemaResolution.js +211 -0
  280. package/dist/schemas.d.ts +5 -0
  281. package/dist/schemas.js +28 -0
  282. package/dist/specs/PreparedProseViewerNativeComponent.d.ts +37 -0
  283. package/dist/specs/PreparedProseViewerNativeComponent.js +6 -0
  284. package/dist/useEditorToolbarInteractions.d.ts +12 -0
  285. package/dist/useEditorToolbarInteractions.js +218 -0
  286. package/dist/useEditorToolbarItems.d.ts +8 -0
  287. package/dist/useEditorToolbarItems.js +280 -0
  288. package/dist/useEditorToolbarPresentation.d.ts +4 -0
  289. package/dist/useEditorToolbarPresentation.js +203 -0
  290. package/dist/useEditorToolbarState.d.ts +63 -0
  291. package/dist/useEditorToolbarState.js +108 -0
  292. package/dist/useFocusPreservingFrames.d.ts +17 -0
  293. package/dist/useFocusPreservingFrames.js +108 -0
  294. package/dist/useNativeEditor.d.ts +66 -0
  295. package/dist/useNativeEditor.js +370 -0
  296. package/dist/useRichTextEditorCommands.d.ts +21 -0
  297. package/dist/useRichTextEditorCommands.js +299 -0
  298. package/dist/useRichTextEditorEvents.d.ts +18 -0
  299. package/dist/useRichTextEditorEvents.js +216 -0
  300. package/dist/useRichTextEditorMentions.d.ts +11 -0
  301. package/dist/useRichTextEditorMentions.js +316 -0
  302. package/dist/useRichTextEditorPresentation.d.ts +5 -0
  303. package/dist/useRichTextEditorPresentation.js +178 -0
  304. package/dist/useRichTextEditorState.d.ts +180 -0
  305. package/dist/useRichTextEditorState.js +405 -0
  306. package/dist/useRichTextEditorUpdates.d.ts +10 -0
  307. package/dist/useRichTextEditorUpdates.js +308 -0
  308. package/dist/useViewerAtoms.d.ts +38 -0
  309. package/dist/useViewerAtoms.js +288 -0
  310. package/expo-module.config.json +13 -0
  311. package/ios/EditorAddons.swift +354 -0
  312. package/ios/EditorCodeHighlighting.swift +184 -0
  313. package/ios/EditorCore.xcframework/Info.plist +44 -0
  314. package/ios/EditorCore.xcframework/ios-arm64/libeditor_core.a +0 -0
  315. package/ios/EditorCore.xcframework/ios-arm64_x86_64-simulator/libeditor_core.a +0 -0
  316. package/ios/EditorInteractionOverlays.swift +697 -0
  317. package/ios/EditorLayoutManager.swift +971 -0
  318. package/ios/EditorNodeTypes.swift +37 -0
  319. package/ios/EditorStyleSheet.swift +461 -0
  320. package/ios/EditorTextView+AttributedPatch.swift +305 -0
  321. package/ios/EditorTextView+Binding.swift +61 -0
  322. package/ios/EditorTextView+Caret.swift +333 -0
  323. package/ios/EditorTextView+Commands.swift +203 -0
  324. package/ios/EditorTextView+Delegate.swift +65 -0
  325. package/ios/EditorTextView+Diagnostics.swift +225 -0
  326. package/ios/EditorTextView+DragDrop.swift +290 -0
  327. package/ios/EditorTextView+ExternalComposition.swift +364 -0
  328. package/ios/EditorTextView+Images.swift +354 -0
  329. package/ios/EditorTextView+InputTraits.swift +200 -0
  330. package/ios/EditorTextView+KeyboardInput.swift +318 -0
  331. package/ios/EditorTextView+Layout.swift +245 -0
  332. package/ios/EditorTextView+MarkedText.swift +267 -0
  333. package/ios/EditorTextView+NativeInputLifecycle.swift +372 -0
  334. package/ios/EditorTextView+NativeMutation.swift +471 -0
  335. package/ios/EditorTextView+Reconciliation.swift +97 -0
  336. package/ios/EditorTextView+RenderPatch.swift +573 -0
  337. package/ios/EditorTextView+Rendering.swift +539 -0
  338. package/ios/EditorTextView+Selection.swift +542 -0
  339. package/ios/EditorTextView.swift +953 -0
  340. package/ios/EditorTheme.swift +626 -0
  341. package/ios/EditorV2Adapter+Commands.swift +204 -0
  342. package/ios/EditorV2Adapter+Envelope.swift +238 -0
  343. package/ios/EditorV2Adapter+Mutation.swift +392 -0
  344. package/ios/EditorV2Adapter+Registry.swift +185 -0
  345. package/ios/EditorV2Adapter+RenderState.swift +360 -0
  346. package/ios/EditorV2Adapter+RenderValidation.swift +420 -0
  347. package/ios/EditorV2Adapter+Selection.swift +329 -0
  348. package/ios/EditorV2Adapter+TextCommands.swift +430 -0
  349. package/ios/EditorV2Adapter.swift +376 -0
  350. package/ios/EditorV2Shadow.swift +353 -0
  351. package/ios/Generated_editor_core.swift +2378 -0
  352. package/ios/NativeCodeHighlighting.swift +159 -0
  353. package/ios/NativeCollaborationSocket.swift +144 -0
  354. package/ios/NativeCollaborationTransport+Protocol.swift +258 -0
  355. package/ios/NativeCollaborationTransport+Socket.swift +379 -0
  356. package/ios/NativeCollaborationTransport+Validation.swift +103 -0
  357. package/ios/NativeCollaborationTransport.swift +322 -0
  358. package/ios/NativeCollaborationTransportRegistry.swift +521 -0
  359. package/ios/NativeEditorExpoView+AccessoryRetry.swift +219 -0
  360. package/ios/NativeEditorExpoView+Binding.swift +268 -0
  361. package/ios/NativeEditorExpoView+Diagnostics.swift +66 -0
  362. package/ios/NativeEditorExpoView+Events.swift +131 -0
  363. package/ios/NativeEditorExpoView+Focus.swift +169 -0
  364. package/ios/NativeEditorExpoView+MentionRetry.swift +288 -0
  365. package/ios/NativeEditorExpoView+Mentions.swift +288 -0
  366. package/ios/NativeEditorExpoView+Properties.swift +300 -0
  367. package/ios/NativeEditorExpoView+Toolbar.swift +86 -0
  368. package/ios/NativeEditorExpoView+Updates.swift +312 -0
  369. package/ios/NativeEditorExpoView.swift +349 -0
  370. package/ios/NativeEditorModule.swift +856 -0
  371. package/ios/NativeEditorViewRegistry.swift +226 -0
  372. package/ios/NativeToolbar+ButtonStyle.swift +214 -0
  373. package/ios/NativeToolbar+Buttons.swift +228 -0
  374. package/ios/NativeToolbar+Diagnostics.swift +114 -0
  375. package/ios/NativeToolbar+Menu.swift +101 -0
  376. package/ios/NativeToolbar+Models.swift +519 -0
  377. package/ios/NativeToolbar+Placeholder.swift +39 -0
  378. package/ios/NativeToolbar.swift +612 -0
  379. package/ios/OrderedListMarkerFormatter.swift +103 -0
  380. package/ios/PositionBridge.swift +596 -0
  381. package/ios/ProseViewerView.swift +462 -0
  382. package/ios/RenderBridge+Atoms.swift +288 -0
  383. package/ios/RenderBridge+Attachments.swift +246 -0
  384. package/ios/RenderBridge+BlockBoundaries.swift +313 -0
  385. package/ios/RenderBridge+Style.swift +343 -0
  386. package/ios/RenderBridge.swift +704 -0
  387. package/ios/RichTextEditorView.swift +930 -0
  388. package/ios/SharedNativeImagePipeline+Cache.swift +189 -0
  389. package/ios/SharedNativeImagePipeline+Transport.swift +328 -0
  390. package/ios/SharedNativeImagePipeline.swift +533 -0
  391. package/ios/Viewer/CoreTextProseLayoutEngine+AttributedText.swift +436 -0
  392. package/ios/Viewer/CoreTextProseLayoutEngine+Models.swift +322 -0
  393. package/ios/Viewer/CoreTextProseLayoutEngine.swift +635 -0
  394. package/ios/Viewer/Fabric/PREPPreparedProseViewerComponentView.h +4 -0
  395. package/ios/Viewer/Fabric/PREPPreparedProseViewerComponentView.mm +767 -0
  396. package/ios/Viewer/Fabric/PreparedProseMeasurementsManager.mm +118 -0
  397. package/ios/Viewer/NativeSVGImageDecoder.h +9 -0
  398. package/ios/Viewer/NativeSVGImageDecoder.mm +106 -0
  399. package/ios/Viewer/NativeSVGPreflight.h +11 -0
  400. package/ios/Viewer/NativeSVGPreflight.mm +219 -0
  401. package/ios/Viewer/PreparedProseDrawingView.swift +639 -0
  402. package/ios/Viewer/PreparedProseInstrumentation.swift +387 -0
  403. package/ios/Viewer/PreparedProseLayout.swift +326 -0
  404. package/ios/Viewer/PreparedProseLayoutCache.swift +766 -0
  405. package/ios/Viewer/PreparedProseLayoutRegistry+Artifacts.swift +377 -0
  406. package/ios/Viewer/PreparedProseLayoutRegistry+Fabric.swift +582 -0
  407. package/ios/Viewer/PreparedProseLayoutRegistry+FabricOwnership.swift +128 -0
  408. package/ios/Viewer/PreparedProseLayoutRegistry.swift +381 -0
  409. package/ios/Viewer/ViewerDocument.swift +575 -0
  410. package/ios/Viewer/ViewerFontEnvironment.swift +283 -0
  411. package/ios/Viewer/ViewerImagePipeline.swift +478 -0
  412. package/ios/editor_coreFFI/editor_coreFFI.h +1023 -0
  413. package/ios/editor_coreFFI/module.modulemap +7 -0
  414. package/package.json +151 -0
  415. package/react-native.config.js +17 -0
  416. package/rust/android/arm64-v8a/libeditor_core.so +0 -0
  417. package/rust/android/armeabi-v7a/libeditor_core.so +0 -0
  418. package/rust/android/x86/libeditor_core.so +0 -0
  419. package/rust/android/x86_64/libeditor_core.so +0 -0
  420. package/rust/bindings/kotlin/uniffi/editor_core/editor_core.kt +3146 -0
  421. package/src/AtomHost.tsx +180 -0
  422. package/src/DefaultAtomChip.tsx +27 -0
  423. package/src/EditorAddon.ts +65 -0
  424. package/src/EditorAddonNormalization.ts +49 -0
  425. package/src/EditorMentionThemeNormalization.ts +25 -0
  426. package/src/EditorMentionThemeValidation.ts +133 -0
  427. package/src/EditorStyleSheet.ts +9 -0
  428. package/src/EditorStyleSheetNormalization.ts +219 -0
  429. package/src/EditorStyleSheetTypes.ts +189 -0
  430. package/src/EditorTheme.ts +196 -0
  431. package/src/EditorToolbar.tsx +31 -0
  432. package/src/EditorToolbarComponent.tsx +23 -0
  433. package/src/EditorToolbarItems.tsx +64 -0
  434. package/src/EditorToolbarRegistry.tsx +254 -0
  435. package/src/EditorToolbarTypes.tsx +322 -0
  436. package/src/EditorToolbarVisuals.tsx +270 -0
  437. package/src/EditorUpdateRevision.ts +26 -0
  438. package/src/ExternalTextComposition.ts +658 -0
  439. package/src/ImageLoadingPolicy.ts +125 -0
  440. package/src/NativeEditorBoundaryError.ts +345 -0
  441. package/src/NativeEditorBridge.ts +93 -0
  442. package/src/NativeEditorCollaborationTransport.ts +493 -0
  443. package/src/NativeEditorCreateConfig.ts +326 -0
  444. package/src/NativeEditorCreateJson.ts +579 -0
  445. package/src/NativeEditorCreateValidation.ts +178 -0
  446. package/src/NativeEditorDocumentBridge.ts +485 -0
  447. package/src/NativeEditorDocumentHandle.ts +168 -0
  448. package/src/NativeEditorLocalAwareness.ts +168 -0
  449. package/src/NativeEditorNativeModule.ts +97 -0
  450. package/src/NativeEditorRenderNormalization.ts +320 -0
  451. package/src/NativeEditorResultNormalization.ts +469 -0
  452. package/src/NativeEditorTypes.ts +366 -0
  453. package/src/NativeEditorV2Decimal.ts +13 -0
  454. package/src/NativeProseViewer.tsx +356 -0
  455. package/src/NativeRichTextEditor.tsx +33 -0
  456. package/src/ResourceLimits.ts +187 -0
  457. package/src/RichTextEditor.tsx +27 -0
  458. package/src/RichTextEditorNativeTypes.tsx +144 -0
  459. package/src/RichTextEditorNativeView.tsx +21 -0
  460. package/src/RichTextEditorSerialization.tsx +381 -0
  461. package/src/RichTextEditorTypes.tsx +327 -0
  462. package/src/ViewerConfiguration.ts +23 -0
  463. package/src/YjsCollaboration.ts +692 -0
  464. package/src/addons.ts +311 -0
  465. package/src/atomConstants.ts +3 -0
  466. package/src/atomInstances.ts +123 -0
  467. package/src/atomPolicy.ts +47 -0
  468. package/src/atomUpdates.ts +52 -0
  469. package/src/atoms.ts +379 -0
  470. package/src/attributeValidation.ts +116 -0
  471. package/src/contentExpression.ts +338 -0
  472. package/src/index.ts +295 -0
  473. package/src/listMarkers.ts +18 -0
  474. package/src/schemaDefinition.ts +395 -0
  475. package/src/schemaDocument.ts +92 -0
  476. package/src/schemaDocumentConstruction.ts +148 -0
  477. package/src/schemaNormalization.ts +367 -0
  478. package/src/schemaPresets.ts +250 -0
  479. package/src/schemaResolution.ts +242 -0
  480. package/src/schemas.ts +43 -0
  481. package/src/specs/PreparedProseViewerNativeComponent.ts +40 -0
  482. package/src/useEditorToolbarInteractions.tsx +329 -0
  483. package/src/useEditorToolbarItems.tsx +390 -0
  484. package/src/useEditorToolbarPresentation.tsx +483 -0
  485. package/src/useEditorToolbarState.tsx +172 -0
  486. package/src/useFocusPreservingFrames.ts +171 -0
  487. package/src/useNativeEditor.ts +534 -0
  488. package/src/useRichTextEditorCommands.tsx +478 -0
  489. package/src/useRichTextEditorEvents.tsx +342 -0
  490. package/src/useRichTextEditorMentions.tsx +441 -0
  491. package/src/useRichTextEditorPresentation.tsx +563 -0
  492. package/src/useRichTextEditorState.tsx +620 -0
  493. package/src/useRichTextEditorUpdates.tsx +403 -0
  494. package/src/useViewerAtoms.tsx +427 -0
@@ -0,0 +1,312 @@
1
+ import ExpoModulesCore
2
+ import UIKit
3
+
4
+ extension NativeEditorExpoView {
5
+ func setPendingEditorUpdateJson(_ editorUpdateJson: String?) {
6
+ lastEditorUpdateJSONProp = editorUpdateJson
7
+ pendingEditorUpdateJSON = editorUpdateJson
8
+ if editorUpdateJson == nil {
9
+ pendingEditorUpdateEditorId = nil
10
+ }
11
+ }
12
+
13
+ func setPendingEditorUpdateEditorId(_ editorUpdateEditorId: String?) {
14
+ guard let editorUpdateEditorId,
15
+ let canonicalEditorId = v2CanonicalUInt64String(editorUpdateEditorId),
16
+ canonicalEditorId != "0"
17
+ else {
18
+ pendingEditorUpdateEditorId = nil
19
+ return
20
+ }
21
+ pendingEditorUpdateEditorId = canonicalEditorId
22
+ }
23
+
24
+ func setPendingEditorUpdateRevision(_ editorUpdateRevision: Int) {
25
+ if editorUpdateRevision != 0, pendingEditorUpdateJSON == nil {
26
+ pendingEditorUpdateJSON = lastEditorUpdateJSONProp
27
+ }
28
+ pendingEditorUpdateRevision = editorUpdateRevision
29
+ }
30
+
31
+ func applyPendingEditorUpdateIfNeeded() {
32
+ guard pendingEditorUpdateRevision != 0 else { return }
33
+ guard pendingEditorUpdateRevision != appliedEditorUpdateRevision else { return }
34
+ let pendingRevision = pendingEditorUpdateRevision
35
+ guard let updateJSON = pendingEditorUpdateJSON else {
36
+ reportRejectedEditorUpdateEnvelope(
37
+ "external editor update JSON is missing",
38
+ fallbackClassification: "missingUpdateJSON"
39
+ )
40
+ consumePendingEditorUpdate(revision: pendingRevision)
41
+ return
42
+ }
43
+ switch applyEditorUpdateOutcome(updateJSON, sourceEditorId: pendingEditorUpdateEditorId, resetJSON: pendingEditorUpdateResetJSON) {
44
+ case .applied:
45
+ consumePendingEditorUpdate(revision: pendingRevision)
46
+ case .retryableDeferred:
47
+ schedulePendingEditorUpdateRetry()
48
+ case .rejected:
49
+ // Mark this prop revision consumed before discarding its envelope:
50
+ // OnViewDidUpdateProps can run again with the same values, but a
51
+ // permanent rejection must not report or retry a second time.
52
+ if let sourceEditorId = pendingEditorUpdateEditorId,
53
+ richTextView.editorId != 0,
54
+ sourceEditorId != String(richTextView.editorId) {
55
+ pendingEditorUpdateEditorId = nil
56
+ }
57
+ consumePendingEditorUpdate(revision: pendingRevision)
58
+ }
59
+ }
60
+
61
+ private func consumePendingEditorUpdate(revision: Int) {
62
+ appliedEditorUpdateRevision = revision
63
+ pendingEditorUpdateJSON = nil
64
+ pendingEditorUpdateRevision = 0
65
+ pendingEditorUpdateRetryScheduled = false
66
+ pendingEditorUpdateRetryEditorId = nil
67
+ pendingEditorUpdateRetryGeneration &+= 1
68
+ }
69
+
70
+ private func schedulePendingEditorUpdateRetry() {
71
+ guard !pendingEditorUpdateRetryScheduled else { return }
72
+ pendingEditorUpdateRetryEditorId = richTextView.editorId
73
+ pendingEditorUpdateRetryScheduled = true
74
+ pendingEditorUpdateRetryGeneration &+= 1
75
+ let retryGeneration = pendingEditorUpdateRetryGeneration
76
+ DispatchQueue.main.async { [weak self] in
77
+ guard let self else { return }
78
+ guard retryGeneration == self.pendingEditorUpdateRetryGeneration else {
79
+ return
80
+ }
81
+ guard self.pendingEditorUpdateRetryEditorId == self.richTextView.editorId else {
82
+ self.pendingEditorUpdateRetryScheduled = false
83
+ self.clearPendingEditorUpdateRetries()
84
+ return
85
+ }
86
+ self.pendingEditorUpdateRetryScheduled = false
87
+ self.pendingEditorUpdateRetryEditorId = nil
88
+ self.applyPendingEditorUpdateIfNeeded()
89
+ }
90
+ }
91
+
92
+ func beginExternalTextComposition(sessionId: String) -> String {
93
+ richTextView.textView.beginExternalTextComposition(sessionId: sessionId)
94
+ }
95
+
96
+ func updateExternalTextComposition(sessionId: String, text: String) -> String {
97
+ richTextView.textView.updateExternalTextComposition(sessionId: sessionId, text: text)
98
+ }
99
+
100
+ func commitExternalTextComposition(sessionId: String, finalText: String) -> String {
101
+ richTextView.textView.commitExternalTextComposition(
102
+ sessionId: sessionId,
103
+ finalText: finalText
104
+ )
105
+ }
106
+
107
+ func cancelExternalTextComposition(sessionId: String, cause: String) -> String {
108
+ richTextView.textView.cancelExternalTextComposition(sessionId: sessionId, cause: cause)
109
+ }
110
+
111
+ private func reportRejectedEditorUpdateEnvelope(
112
+ _ message: String,
113
+ fallbackClassification: String
114
+ ) {
115
+ if let adapter = EditorV2Registry.adapter(forLegacyId: richTextView.editorId) {
116
+ adapter.rejectExternalRenderEnvelope(message)
117
+ } else {
118
+ editorUpdateInternalRejections.append(
119
+ "boundary/FFI_RESULT_INVALID/\(fallbackClassification)"
120
+ )
121
+ }
122
+ }
123
+
124
+ func applyRemoteCommitRefresh() {
125
+ // Preparing an external update commits a live composition. The commit
126
+ // re-bases the adapter itself, so leave the half-typed word alone.
127
+ guard !richTextView.textView.hasPendingCompositionForExternalRefresh else { return }
128
+ let boundEditorId = richTextView.editorId
129
+ guard boundEditorId != 0,
130
+ let adapter = EditorV2Registry.adapter(forLegacyId: boundEditorId),
131
+ !adapter.isDestroyed
132
+ else {
133
+ return
134
+ }
135
+ let autonomousOwner = autonomousErrorBindingAdapter === adapter
136
+ && autonomousErrorBindingToken.map { adapter.isNativeBindingOwner(token: $0) } == true
137
+ guard autonomousOwner || richTextView.textView.ownsNativeBinding(adapter) else { return }
138
+ let preflight = richTextView.textView.prepareForExternalEditorUpdateResult()
139
+ guard preflight.ready else { return }
140
+ guard let update = preflight.adoptedUpdateJSON
141
+ ?? adapter.refreshFromRustState(mirrorSelection: nil)
142
+ else {
143
+ return
144
+ }
145
+ if !richTextView.textView.applyUpdateJSON(update),
146
+ let recovery = adapter.recoverNativeRender() {
147
+ richTextView.textView.applyUpdateJSON(recovery)
148
+ }
149
+ }
150
+
151
+ private func applyEditorUpdateOutcome(
152
+ _ updateJson: String,
153
+ sourceEditorId: String?,
154
+ resetJSON: String? = nil
155
+ ) -> EditorUpdateApplyOutcome {
156
+ let boundEditorId = richTextView.editorId
157
+ guard boundEditorId != 0 else {
158
+ reportRejectedEditorUpdateEnvelope(
159
+ "external editor update has no bound adapter",
160
+ fallbackClassification: "missingAdapter"
161
+ )
162
+ return .rejected
163
+ }
164
+ guard let sourceEditorId else {
165
+ reportRejectedEditorUpdateEnvelope(
166
+ "external editor update source id is missing or malformed",
167
+ fallbackClassification: "malformedSourceEditorId"
168
+ )
169
+ return .rejected
170
+ }
171
+ guard sourceEditorId == String(boundEditorId) else {
172
+ reportRejectedEditorUpdateEnvelope(
173
+ "external editor update source does not match the bound canonical editor id",
174
+ fallbackClassification: "sourceEditorMismatch"
175
+ )
176
+ return .rejected
177
+ }
178
+ guard let adapter = EditorV2Registry.adapter(forLegacyId: boundEditorId) else {
179
+ reportRejectedEditorUpdateEnvelope(
180
+ "external editor update adapter is missing",
181
+ fallbackClassification: "missingAdapter"
182
+ )
183
+ return .rejected
184
+ }
185
+ guard !adapter.isDestroyed else {
186
+ adapter.rejectExternalRenderEnvelope("external editor update adapter is destroyed")
187
+ return .rejected
188
+ }
189
+ // A malformed external envelope is permanent, even if UIKit is in a
190
+ // transient composition that would otherwise make application
191
+ // retryable. Classify it before entering composition preflight.
192
+ guard adapter.validateExternalRender(updateJson) else {
193
+ return .rejected
194
+ }
195
+ if let resetJSON {
196
+ guard adapter.validateExternalReset(resetJSON) else { return .rejected }
197
+ isApplyingJSUpdate = true
198
+ defer { isApplyingJSUpdate = false }
199
+ richTextView.textView.discardTransientNativeInputForEditorReset()
200
+ guard let update = adapter.adoptExternalReset(updateJson, resetJSON: resetJSON) else {
201
+ return .rejected
202
+ }
203
+ clearPendingViewCommandUpdateRetry()
204
+ let applied = imageLoadOwner.withCurrent {
205
+ richTextView.textView.applyUpdateJSON(update)
206
+ }
207
+ if applied, renderRevision(fromUpdateJSON: update)?.document != renderRevision(fromUpdateJSON: updateJson)?.document {
208
+ isApplyingJSUpdate = false
209
+ editorTextView(richTextView.textView, didReceiveUpdate: update)
210
+ }
211
+ return applied ? .applied : .rejected
212
+ }
213
+ if isSupersededEditorUpdate(updateJson) {
214
+ return .applied
215
+ }
216
+ let preflight = richTextView.textView.prepareForExternalEditorUpdateResult()
217
+ guard preflight.ready else {
218
+ return .retryableDeferred
219
+ }
220
+ if preflight.adoptedUpdateJSON != nil {
221
+ return .applied
222
+ }
223
+ let adoptedUpdateJSON = adapter.adoptExternalRender(updateJson)
224
+ guard let adoptedUpdateJSON else {
225
+ // The adapter owns strict-parser and destroyed-race reporting.
226
+ // Do not add a second view-side record for the same rejection.
227
+ return .rejected
228
+ }
229
+ isApplyingJSUpdate = true
230
+ defer { isApplyingJSUpdate = false }
231
+ imageLoadOwner.withCurrent {
232
+ // The adapter cache and the payload are paired by the same
233
+ // editor-scoped call above; do not let the view display a render
234
+ // whose revision has not already been adopted for native input.
235
+ _ = richTextView.textView.applyUpdateJSON(adoptedUpdateJSON)
236
+ }
237
+ return .applied
238
+ }
239
+
240
+ /// Apply an editor update from JS. Sets the echo-suppression flag so the
241
+ /// resulting delegate callback is NOT re-dispatched back to JS.
242
+ @discardableResult
243
+ func applyEditorUpdate(_ updateJson: String) -> Bool {
244
+ let sourceEditorId = richTextView.editorId == 0 ? nil : String(richTextView.editorId)
245
+ switch applyEditorUpdateOutcome(updateJson, sourceEditorId: sourceEditorId) {
246
+ case .applied:
247
+ return true
248
+ case .retryableDeferred:
249
+ scheduleViewCommandUpdateRetry(updateJson, sourceEditorId: sourceEditorId)
250
+ return false
251
+ case .rejected:
252
+ return false
253
+ }
254
+ }
255
+
256
+ private func scheduleViewCommandUpdateRetry(_ updateJson: String, sourceEditorId: String?) {
257
+ pendingViewCommandUpdateJSON = updateJson
258
+ pendingViewCommandUpdateEditorId = richTextView.editorId
259
+ guard !pendingViewCommandUpdateRetryScheduled else { return }
260
+ pendingViewCommandUpdateRetryScheduled = true
261
+ pendingViewCommandUpdateRetryGeneration &+= 1
262
+ let retryGeneration = pendingViewCommandUpdateRetryGeneration
263
+ DispatchQueue.main.async { [weak self] in
264
+ guard let self else { return }
265
+ guard retryGeneration == self.pendingViewCommandUpdateRetryGeneration else {
266
+ return
267
+ }
268
+ guard self.pendingViewCommandUpdateJSON != nil else {
269
+ self.pendingViewCommandUpdateRetryScheduled = false
270
+ return
271
+ }
272
+ guard self.pendingViewCommandUpdateEditorId == self.richTextView.editorId else {
273
+ self.pendingViewCommandUpdateJSON = nil
274
+ self.pendingViewCommandUpdateEditorId = nil
275
+ self.pendingViewCommandUpdateRetryScheduled = false
276
+ return
277
+ }
278
+ guard self.richTextView.editorId != 0 else {
279
+ self.pendingViewCommandUpdateJSON = nil
280
+ self.pendingViewCommandUpdateEditorId = nil
281
+ self.pendingViewCommandUpdateRetryScheduled = false
282
+ return
283
+ }
284
+ let updateJSON = self.pendingViewCommandUpdateJSON
285
+ self.pendingViewCommandUpdateJSON = nil
286
+ self.pendingViewCommandUpdateEditorId = nil
287
+ self.pendingViewCommandUpdateRetryScheduled = false
288
+ guard let updateJSON else { return }
289
+ switch self.applyEditorUpdateOutcome(
290
+ updateJSON,
291
+ sourceEditorId: sourceEditorId
292
+ ) {
293
+ case .applied, .rejected:
294
+ return
295
+ case .retryableDeferred:
296
+ self.scheduleViewCommandUpdateRetry(updateJSON, sourceEditorId: sourceEditorId)
297
+ }
298
+ }
299
+ }
300
+
301
+ func prepareForEditorCommandJSON() -> String {
302
+ isApplyingJSUpdate = true
303
+ defer { isApplyingJSUpdate = false }
304
+ let preparation = richTextView.textView.prepareForExternalEditorCommand()
305
+ return NativeEditorViewRegistry.commandPreparationJSON(
306
+ ready: preparation.ready,
307
+ updateJSON: preparation.updateJSON,
308
+ blockedReason: preparation.blockedReason
309
+ )
310
+ }
311
+
312
+ }
@@ -0,0 +1,349 @@
1
+ import ExpoModulesCore
2
+ import UIKit
3
+
4
+ final class PendingJSONRetry {
5
+ struct Token {
6
+ let generation: UInt64
7
+ let attempt: Int
8
+ }
9
+
10
+ var json: String?
11
+ var editorId: UInt64?
12
+ private var scheduled = false
13
+ var generation: UInt64 = 0
14
+ private(set) var attempts = 0
15
+
16
+ func clear() {
17
+ json = nil
18
+ editorId = nil
19
+ scheduled = false
20
+ attempts = 0
21
+ generation &+= 1
22
+ }
23
+
24
+ func schedule(
25
+ json: String?,
26
+ editorId: UInt64,
27
+ maxAttempts: Int?
28
+ ) -> Token? {
29
+ self.json = json
30
+ self.editorId = editorId
31
+ guard !scheduled else { return nil }
32
+ if let maxAttempts, attempts >= maxAttempts { return nil }
33
+ attempts += 1
34
+ scheduled = true
35
+ generation &+= 1
36
+ return Token(generation: generation, attempt: attempts)
37
+ }
38
+
39
+ func consume(_ token: Token) -> (json: String?, editorId: UInt64?)? {
40
+ guard token.generation == generation else { return nil }
41
+ let result = (json, editorId)
42
+ json = nil
43
+ editorId = nil
44
+ scheduled = false
45
+ return result
46
+ }
47
+ }
48
+
49
+ class NativeEditorExpoView: ExpoView, EditorTextViewDelegate, UIGestureRecognizerDelegate {
50
+ static let layoutEpsilon: CGFloat = 0.5
51
+ static let nativeActionRetryDelay: TimeInterval = 0.016
52
+ static let maxPendingUpdateRetryAttempts = 5
53
+
54
+ // MARK: - Subviews
55
+
56
+ let richTextView: RichTextEditorView
57
+ let accessoryToolbar = EditorAccessoryToolbarView(
58
+ frame: .zero,
59
+ inputViewStyle: .keyboard
60
+ )
61
+ let accessoryPlaceholder = EditorAccessoryPlaceholderView(frame: .zero)
62
+ var toolbarFramesInWindow: [CGRect] = []
63
+ var lastToolbarTouchUptime: TimeInterval = -Double.infinity
64
+ var didApplyAutoFocus = false
65
+ var toolbarState = NativeToolbarState.empty
66
+ var toolbarItems: [NativeToolbarItem] = NativeToolbarItem.defaults
67
+ var showsToolbar = true
68
+ var toolbarPlacement = "keyboard"
69
+ var heightBehavior: EditorHeightBehavior = .fixed
70
+ private var lastAutoGrowWidth: CGFloat = 0
71
+ var lastPublishedAutoGrowHeight: CGFloat?
72
+ var addons = NativeEditorAddons(mentions: nil)
73
+ var mentionQueryState: MentionQueryState?
74
+ var lastMentionEventJSON: String?
75
+ var desiredThemeJSON: String?
76
+ var desiredAtomsJSON: String?
77
+ let imageLoadOwner = RenderImageLoadOwner(policy: .default)
78
+ var lastThemeJSON: String?
79
+ var lastAddonsJSON: String?
80
+ var lastAtomsJSON: String?
81
+ var lastRemoteSelectionsJSON: String?
82
+ var lastToolbarItemsJSON: String?
83
+ var lastToolbarFrameJSON: String?
84
+ private var isReparentingAtomChild = false
85
+ private var mountedReactChildren: [UIView] = []
86
+ private var mountedAtomKeys: [ObjectIdentifier: String] = [:]
87
+ var lastEditorUpdateJSONProp: String?
88
+ var pendingEditorUpdateResetJSON: String?
89
+ var pendingEditorUpdateJSON: String?
90
+ var pendingEditorUpdateEditorId: String?
91
+ var pendingEditorUpdateRevision = 0
92
+ var appliedEditorUpdateRevision = 0
93
+ var renderedRevision: (document: UInt64, state: UInt64)?
94
+ var pendingEditorUpdateRetryScheduled = false
95
+ var pendingEditorUpdateRetryEditorId: UInt64?
96
+ var pendingEditorUpdateRetryGeneration: UInt64 = 0
97
+ var editorUpdateInternalRejections: [String] = []
98
+ var pendingViewCommandUpdateJSON: String?
99
+ var pendingViewCommandUpdateEditorId: UInt64?
100
+ var pendingViewCommandUpdateRetryScheduled = false
101
+ var pendingViewCommandUpdateRetryGeneration: UInt64 = 0
102
+ var pendingEditableRetryValue: Bool?
103
+ var pendingEditableRetryEditorId: UInt64?
104
+ var pendingEditableRetryScheduled = false
105
+ var pendingEditableRetryGeneration: UInt64 = 0
106
+ let pendingThemeRetry = PendingJSONRetry()
107
+ let pendingAtomsRetry = PendingJSONRetry()
108
+ var pendingAtomsWakeScheduled = false
109
+ var atomsRetryAttemptsForTesting: Int { pendingAtomsRetry.attempts }
110
+ var blockAtomConfigurationApplyForTesting = false
111
+ var pendingAccessoryRetryActions: [PendingAccessoryRetryAction] = []
112
+ var invalidatedAccessoryRetryActions = Set<PendingAccessoryRetryAction>()
113
+ var pendingAccessoryRetryEditorId: UInt64?
114
+ var pendingAccessoryRetryScheduled = false
115
+ var pendingAccessoryRetryGeneration: UInt64 = 0
116
+ var pendingMentionSuggestionRetry: PendingMentionSuggestionRetry?
117
+ var pendingMentionSuggestionRetryScheduled = false
118
+ var pendingMentionSuggestionRetryGeneration: UInt64 = 0
119
+ lazy var outsideTapGestureRecognizer: UITapGestureRecognizer = {
120
+ let recognizer = UITapGestureRecognizer(
121
+ target: self,
122
+ action: #selector(handleOutsideTap(_:))
123
+ )
124
+ recognizer.cancelsTouchesInView = false
125
+ recognizer.delegate = self
126
+ return recognizer
127
+ }()
128
+ weak var gestureWindow: UIWindow?
129
+
130
+ /// Guard flag to suppress echo: when JS applies an update via the view
131
+ /// command, the resulting delegate callback must NOT be re-dispatched
132
+ /// back to JS.
133
+ var isApplyingJSUpdate = false
134
+
135
+ // MARK: - Event Dispatchers (wired by Expo Modules via reflection)
136
+
137
+ let onEditorUpdate = EventDispatcher()
138
+ let onSelectionChange = EventDispatcher()
139
+ let onFocusChange = EventDispatcher()
140
+ let onContentHeightChange = EventDispatcher()
141
+ let onAtomLayout = EventDispatcher()
142
+ let onToolbarAction = EventDispatcher()
143
+ let onAddonEvent = EventDispatcher()
144
+ let onEditorError = EventDispatcher()
145
+ let onExternalTextCompositionEnd = EventDispatcher()
146
+ /// Native integration tests capture the exact payload production sends to
147
+ /// Expo without assigning adapter callbacks directly.
148
+ var onEditorErrorForTesting: (([String: Any]) -> Void)?
149
+ var onExternalTextCompositionEndForTesting: (([String: Any]) -> Void)?
150
+ var autonomousErrorBindingAdapter: EditorV2Adapter?
151
+ var autonomousErrorBindingEditorId: String?
152
+ var autonomousErrorBindingToken: UUID?
153
+ var autonomousErrorBindingGeneration: UInt64 = 0
154
+ var pendingAutonomousErrors: [UUID: PendingAutonomousError] = [:]
155
+ var lastEmittedContentHeight: CGFloat = 0
156
+ var cachedAutoGrowContentHeight: CGFloat = 0
157
+ var lastAddonEventJSONForTestingValue: String?
158
+
159
+ enum EditorUpdateApplyOutcome {
160
+ case applied
161
+ case retryableDeferred
162
+ case rejected
163
+ }
164
+
165
+ enum PendingAccessoryRetryAction: Hashable {
166
+ case reloadInputViews
167
+ case refreshMentionQuery
168
+ case clearMentionQueryState
169
+ case updateAccessoryToolbarVisibility
170
+ }
171
+
172
+ struct PendingMentionSuggestionRetry {
173
+ let suggestionKey: String
174
+ let editorId: UInt64
175
+ let trigger: String
176
+ let query: String
177
+ let anchor: UInt32
178
+ let head: UInt32
179
+ let documentVersion: String?
180
+ let textSnapshot: String
181
+ }
182
+
183
+ struct PendingAutonomousError {
184
+ let adapter: EditorV2Adapter
185
+ let editorId: String
186
+ let token: UUID
187
+ let generation: UInt64
188
+ let error: FfiError
189
+ }
190
+
191
+ struct MentionRetryTextDiff {
192
+ let start: Int
193
+ let oldEnd: Int
194
+ let newEnd: Int
195
+ }
196
+
197
+ // MARK: - Initialization
198
+
199
+ required init(appContext: AppContext? = nil) {
200
+ richTextView = RichTextEditorView(frame: .zero)
201
+ super.init(appContext: appContext)
202
+ richTextView.imageLoadOwner = imageLoadOwner
203
+ richTextView.onHeightMayChange = { [weak self] measuredHeight in
204
+ guard let self, self.heightBehavior == .autoGrow else { return }
205
+ self.cachedAutoGrowContentHeight = measuredHeight
206
+ self.invalidateIntrinsicContentSize()
207
+ self.emitContentHeightIfNeeded(force: true, measuredHeight: measuredHeight)
208
+ }
209
+ richTextView.onAtomContentWidthChange = { [weak self] width in
210
+ self?.emitAtomLayout(width: width)
211
+ }
212
+ richTextView.textView.editorDelegate = self
213
+ richTextView.textView.onExternalUpdateReadinessMayChange = { [weak self] in
214
+ self?.schedulePendingAtomsWakeIfNeeded()
215
+ }
216
+ configureAccessoryToolbar()
217
+
218
+ NotificationCenter.default.addObserver(
219
+ self,
220
+ selector: #selector(textViewDidBeginEditing(_:)),
221
+ name: UITextView.textDidBeginEditingNotification,
222
+ object: richTextView.textView
223
+ )
224
+ NotificationCenter.default.addObserver(
225
+ self,
226
+ selector: #selector(textViewDidEndEditing(_:)),
227
+ name: UITextView.textDidEndEditingNotification,
228
+ object: richTextView.textView
229
+ )
230
+
231
+ addSubview(richTextView)
232
+ }
233
+
234
+ deinit {
235
+ richTextView.textView.editorDelegate = nil
236
+ richTextView.textView.onExternalUpdateReadinessMayChange = nil
237
+ if let resultJSON = richTextView.textView.discardTransientNativeInputForEditorRebind() {
238
+ dispatchExternalTextCompositionEnd(resultJSON)
239
+ }
240
+ let editorId = richTextView.editorId
241
+ let releasedNativeOwner = ownsNativeBinding(editorId: editorId)
242
+ clearAutonomousErrorBinding()
243
+ NativeEditorViewRegistry.shared.unregister(editorId: editorId, view: self)
244
+ if releasedNativeOwner {
245
+ NativeEditorViewRegistry.shared.nativeOwnerReleased(editorId: editorId, by: self)
246
+ }
247
+ imageLoadOwner.cancelAll()
248
+ NotificationCenter.default.removeObserver(self)
249
+ }
250
+
251
+ // MARK: - Layout
252
+
253
+ override func mountChildComponentView(_ childComponentView: UIView, index: Int) {
254
+ let reactIndex = min(max(index, 0), mountedReactChildren.count)
255
+ mountedReactChildren.insert(childComponentView, at: reactIndex)
256
+ let atomKey = Self.atomKey(for: childComponentView)
257
+ if let atomKey {
258
+ mountedAtomKeys[ObjectIdentifier(childComponentView)] = atomKey
259
+ richTextView.mountAtomChild(childComponentView, atomKey: atomKey)
260
+ } else {
261
+ let nativeSubviewCount = subviews.filter { subview in
262
+ !mountedReactChildren.contains(where: { $0 === subview })
263
+ }.count
264
+ let directIndex = nativeSubviewCount + mountedReactChildren[..<reactIndex].filter {
265
+ mountedAtomKeys[ObjectIdentifier($0)] == nil
266
+ }.count
267
+ super.mountChildComponentView(childComponentView, index: directIndex)
268
+ }
269
+ }
270
+
271
+ override func unmountChildComponentView(_ childComponentView: UIView, index: Int) {
272
+ if let reactIndex = mountedReactChildren.firstIndex(where: { $0 === childComponentView }) {
273
+ mountedReactChildren.remove(at: reactIndex)
274
+ }
275
+ if mountedAtomKeys.removeValue(forKey: ObjectIdentifier(childComponentView)) != nil {
276
+ _ = richTextView.unmountAtomChild(childComponentView)
277
+ childComponentView.removeFromSuperview()
278
+ return
279
+ }
280
+ let directIndex = subviews.firstIndex(where: { $0 === childComponentView }) ?? index
281
+ super.unmountChildComponentView(childComponentView, index: directIndex)
282
+ }
283
+
284
+ override func didAddSubview(_ subview: UIView) {
285
+ super.didAddSubview(subview)
286
+ guard subview !== richTextView,
287
+ !isReparentingAtomChild,
288
+ let atomKey = Self.atomKey(for: subview)
289
+ else { return }
290
+ isReparentingAtomChild = true
291
+ richTextView.mountAtomChild(subview, atomKey: atomKey)
292
+ isReparentingAtomChild = false
293
+ }
294
+
295
+ override var intrinsicContentSize: CGSize {
296
+ guard heightBehavior == .autoGrow else {
297
+ return CGSize(width: UIView.noIntrinsicMetric, height: UIView.noIntrinsicMetric)
298
+ }
299
+ if cachedAutoGrowContentHeight > 0 {
300
+ return CGSize(width: UIView.noIntrinsicMetric, height: cachedAutoGrowContentHeight)
301
+ }
302
+ return richTextView.intrinsicContentSize
303
+ }
304
+
305
+ override func layoutSubviews() {
306
+ super.layoutSubviews()
307
+ richTextView.frame = bounds
308
+ guard heightBehavior == .autoGrow else { return }
309
+ let currentWidth = bounds.width.rounded(.towardZero)
310
+ guard currentWidth != lastAutoGrowWidth else { return }
311
+ lastAutoGrowWidth = currentWidth
312
+ cachedAutoGrowContentHeight = 0
313
+ invalidateIntrinsicContentSize()
314
+ emitContentHeightIfNeeded(force: true)
315
+ }
316
+
317
+ override func didMoveToWindow() {
318
+ super.didMoveToWindow()
319
+ if window == nil {
320
+ let editorId = richTextView.editorId
321
+ let releasedNativeOwner = ownsNativeBinding(editorId: editorId)
322
+ clearAutonomousErrorBinding()
323
+ if releasedNativeOwner {
324
+ NativeEditorViewRegistry.shared.nativeOwnerReleased(editorId: editorId, by: self)
325
+ }
326
+ } else {
327
+ ensureAutonomousErrorBinding()
328
+ applyRemoteCommitRefresh()
329
+ }
330
+ if richTextView.textView.isFirstResponder {
331
+ installOutsideTapRecognizerIfNeeded()
332
+ } else {
333
+ uninstallOutsideTapRecognizer()
334
+ }
335
+ }
336
+
337
+ // MARK: - Autonomous adapter errors
338
+
339
+ var imageLoadingPolicy: ImageLoadingPolicy {
340
+ imageLoadOwner.policy
341
+ }
342
+
343
+ // MARK: - EditorTextViewDelegate
344
+
345
+ var shouldUseSystemAssistantToolbar: Bool {
346
+ false
347
+ }
348
+
349
+ }