@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,267 @@
1
+ import os
2
+ import UIKit
3
+
4
+ extension EditorTextView {
5
+ func captureMarkedTextReplacementRangeIfNeeded() {
6
+ guard markedTextReplacementScalarRange == nil else { return }
7
+
8
+ guard let selectedRange = selectedTextRange else {
9
+ let scalarPos = PositionBridge.cursorScalarOffset(in: self)
10
+ let utf16Pos = PositionBridge.scalarToUtf16Offset(scalarPos, in: lastAuthorizedText)
11
+ markedTextReplacementScalarRange = (from: scalarPos, to: scalarPos)
12
+ markedTextReplacementUtf16Range = NSRange(
13
+ location: utf16Pos,
14
+ length: 0
15
+ )
16
+ return
17
+ }
18
+
19
+ let scalarRange = PositionBridge.textRangeToScalarRange(selectedRange, in: self)
20
+ let startUtf16 = offset(from: beginningOfDocument, to: selectedRange.start)
21
+ let endUtf16 = offset(from: beginningOfDocument, to: selectedRange.end)
22
+
23
+ markedTextReplacementScalarRange = (from: scalarRange.from, to: scalarRange.to)
24
+ markedTextReplacementUtf16Range = NSRange(
25
+ location: min(startUtf16, endUtf16),
26
+ length: abs(endUtf16 - startUtf16)
27
+ )
28
+ }
29
+
30
+ func trackedMarkedTextReplacementRange() -> (from: UInt32, to: UInt32)? {
31
+ if let markedTextReplacementScalarRange {
32
+ return markedTextReplacementScalarRange
33
+ }
34
+ guard let selectedRange = selectedTextRange else { return nil }
35
+ let scalarRange = PositionBridge.textRangeToScalarRange(selectedRange, in: self)
36
+ return (from: scalarRange.from, to: scalarRange.to)
37
+ }
38
+
39
+ func clearMarkedTextTracking() {
40
+ markedTextReplacementScalarRange = nil
41
+ markedTextReplacementUtf16Range = nil
42
+ markedTextCompositionText = nil
43
+ markedTextCompositionIsExplicitlyEmpty = false
44
+ isComposing = false
45
+ }
46
+
47
+ func finishTransientMarkedTextMutation() {
48
+ performTransientTextMutation {
49
+ super.unmarkText()
50
+ }
51
+ clearMarkedTextTracking()
52
+ onExternalUpdateReadinessMayChange?()
53
+ }
54
+
55
+ func performTransientTextMutation(_ action: () -> Void) {
56
+ let wasApplyingRustState = isApplyingRustState
57
+ isApplyingRustState = true
58
+ action()
59
+ isApplyingRustState = wasApplyingRustState
60
+ }
61
+
62
+ func currentMarkedTextForCommit() -> String? {
63
+ if markedTextCompositionIsExplicitlyEmpty { return "" }
64
+ return transientMarkedTextFromAuthorizedDiff()
65
+ ?? markedTextRange.flatMap { text(in: $0) }
66
+ ?? markedTextCompositionText
67
+ }
68
+
69
+ func validatedTrackedMarkedTextForCommit() -> String? {
70
+ guard markedTextReplacementScalarRange != nil || markedTextReplacementUtf16Range != nil else {
71
+ return nil
72
+ }
73
+ if markedTextCompositionIsExplicitlyEmpty { return "" }
74
+ return transientMarkedTextFromAuthorizedDiff()
75
+ ?? markedTextRange.flatMap { text(in: $0) }
76
+ }
77
+
78
+ func refreshMarkedTextCompositionText(fallback: String? = nil) {
79
+ if fallback?.isEmpty == true {
80
+ markedTextCompositionText = ""
81
+ markedTextCompositionIsExplicitlyEmpty = true
82
+ return
83
+ }
84
+ markedTextCompositionIsExplicitlyEmpty = false
85
+ markedTextCompositionText = transientMarkedTextFromAuthorizedDiff()
86
+ ?? markedTextRange.flatMap { text(in: $0) }
87
+ ?? fallback
88
+ }
89
+
90
+ private func transientMarkedTextFromAuthorizedDiff() -> String? {
91
+ guard let replacementRange = markedTextReplacementUtf16Range else { return nil }
92
+
93
+ let currentText = textStorage.string as NSString
94
+ let authorizedText = lastAuthorizedText as NSString
95
+ let replacementEnd = replacementRange.location + replacementRange.length
96
+ guard replacementRange.location >= 0,
97
+ replacementEnd <= authorizedText.length
98
+ else {
99
+ return nil
100
+ }
101
+
102
+ let insertedLength = currentText.length - (authorizedText.length - replacementRange.length)
103
+ guard insertedLength >= 0,
104
+ replacementRange.location + insertedLength <= currentText.length
105
+ else {
106
+ return nil
107
+ }
108
+
109
+ if replacementRange.location > 0 {
110
+ let prefixRange = NSRange(location: 0, length: replacementRange.location)
111
+ guard currentText.substring(with: prefixRange) == authorizedText.substring(with: prefixRange) else {
112
+ return nil
113
+ }
114
+ }
115
+
116
+ let insertedEnd = replacementRange.location + insertedLength
117
+ let authorizedSuffixLength = authorizedText.length - replacementEnd
118
+ let currentSuffixLength = currentText.length - insertedEnd
119
+ guard authorizedSuffixLength == currentSuffixLength else { return nil }
120
+ if authorizedSuffixLength > 0 {
121
+ let authorizedSuffixRange = NSRange(location: replacementEnd, length: authorizedSuffixLength)
122
+ let currentSuffixRange = NSRange(location: insertedEnd, length: currentSuffixLength)
123
+ guard currentText.substring(with: currentSuffixRange)
124
+ == authorizedText.substring(with: authorizedSuffixRange)
125
+ else {
126
+ return nil
127
+ }
128
+ }
129
+
130
+ return currentText.substring(
131
+ with: NSRange(location: replacementRange.location, length: insertedLength)
132
+ )
133
+ }
134
+
135
+ func commitMarkedText(
136
+ _ text: String,
137
+ replacementRange: (from: UInt32, to: UInt32)?
138
+ ) -> String? {
139
+ guard editorId != 0,
140
+ let adapter = EditorV2Registry.adapter(forLegacyId: editorId)
141
+ else {
142
+ return nil
143
+ }
144
+ var adoptedUpdateJSON: String?
145
+ performInterceptedInput(flushPendingNativeTextMutation: false) {
146
+ if let replacementRange {
147
+ if replacementRange.from == replacementRange.to {
148
+ adoptedUpdateJSON = adapter.insertText(text, atScalar: replacementRange.from)
149
+ } else {
150
+ adoptedUpdateJSON = adapter.replaceTextRange(
151
+ from: replacementRange.from,
152
+ to: replacementRange.to,
153
+ with: text
154
+ )
155
+ }
156
+ } else {
157
+ adoptedUpdateJSON = adapter.insertText(
158
+ text,
159
+ atScalar: PositionBridge.cursorScalarOffset(in: self)
160
+ )
161
+ }
162
+ guard let adoptedUpdateJSON else { return }
163
+ applyUpdateJSON(adoptedUpdateJSON)
164
+ }
165
+ return adoptedUpdateJSON
166
+ }
167
+
168
+ func commitMarkedTextWithNativeOutcome(
169
+ _ text: String,
170
+ replacementRange: (from: UInt32, to: UInt32)?
171
+ ) -> EditorV2Adapter.NativeMutationRender? {
172
+ guard editorId != 0,
173
+ let adapter = EditorV2Registry.adapter(forLegacyId: editorId)
174
+ else {
175
+ return nil
176
+ }
177
+ var commit: EditorV2Adapter.NativeMutationRender?
178
+ performInterceptedInput(flushPendingNativeTextMutation: false) {
179
+ if let replacementRange {
180
+ if replacementRange.from == replacementRange.to {
181
+ commit = adapter.insertTextWithNativeOutcome(
182
+ text,
183
+ atScalar: replacementRange.from
184
+ )
185
+ } else {
186
+ commit = adapter.replaceTextRangeWithNativeOutcome(
187
+ from: replacementRange.from,
188
+ to: replacementRange.to,
189
+ with: text
190
+ )
191
+ }
192
+ } else {
193
+ let position = PositionBridge.cursorScalarOffset(in: self)
194
+ commit = adapter.insertTextWithNativeOutcome(text, atScalar: position)
195
+ }
196
+ guard let commit else { return }
197
+ applyUpdateJSON(commit.updateJSON, notifyDelegate: commit.documentChanged)
198
+ }
199
+ return commit
200
+ }
201
+
202
+ func commitActiveMarkedTextBeforeReturn() -> Bool {
203
+ guard markedTextReplacementScalarRange != nil || markedTextRange != nil else {
204
+ return true
205
+ }
206
+
207
+ if markedTextReplacementScalarRange != nil || markedTextReplacementUtf16Range != nil {
208
+ let composedText = currentMarkedTextForCommit()
209
+ let replacementRange = trackedMarkedTextReplacementRange()
210
+ finishTransientMarkedTextMutation()
211
+
212
+ guard shouldCommitMarkedText(composedText, replacementRange: replacementRange) else {
213
+ restoreAuthorizedTextAfterCancelledCompositionIfNeeded()
214
+ return true
215
+ }
216
+ return commitMarkedText(composedText ?? "", replacementRange: replacementRange) != nil
217
+ }
218
+
219
+ let mutation = nativeTextMutationFromAuthorizedDiff(currentText: textStorage.string)
220
+ finishTransientMarkedTextMutation()
221
+ guard let mutation else {
222
+ restoreAuthorizedTextAfterCancelledCompositionIfNeeded()
223
+ return true
224
+ }
225
+
226
+ switch commitNativeTextMutationIfPossible(
227
+ mutation,
228
+ allowAfterBlur: false,
229
+ allowWhileIntercepting: true
230
+ ) {
231
+ case .committed:
232
+ return true
233
+ case .deferred, .rejected:
234
+ restoreAuthorizedTextAfterCancelledCompositionIfNeeded()
235
+ return false
236
+ }
237
+ }
238
+
239
+ func shouldCommitMarkedText(
240
+ _ text: String?,
241
+ replacementRange: (from: UInt32, to: UInt32)?
242
+ ) -> Bool {
243
+ guard let text else { return false }
244
+ if !text.isEmpty { return true }
245
+ guard let replacementRange else { return false }
246
+ return replacementRange.from != replacementRange.to
247
+ }
248
+
249
+ func restoreAuthorizedTextAfterCancelledCompositionIfNeeded() {
250
+ guard editorId != 0 else { return }
251
+ guard textStorage.string != lastAuthorizedText else { return }
252
+
253
+ let stateJSON = EditorV2Shadow.getCurrentState(id: editorId)
254
+ applyUpdateJSON(stateJSON)
255
+ }
256
+
257
+ func previewMarkedTextReplacementRange(
258
+ _ range: (from: UInt32, to: UInt32)?
259
+ ) -> String {
260
+ guard let range else { return "none" }
261
+ let utf16 = markedTextReplacementUtf16Range
262
+ .map { "\($0.location)..<\($0.location + $0.length)" }
263
+ ?? "none"
264
+ return "scalar=\(range.from)..<\(range.to) utf16=\(utf16)"
265
+ }
266
+
267
+ }
@@ -0,0 +1,372 @@
1
+ import os
2
+ import UIKit
3
+
4
+ extension EditorTextView {
5
+ enum NativeTextMutationCommitResult {
6
+ case committed(adoptedUpdateJSON: String)
7
+ case deferred
8
+ case rejected
9
+ }
10
+
11
+ struct NativeTextMutationDrainResult {
12
+ let ready: Bool
13
+ let adoptedUpdateJSON: String?
14
+ }
15
+
16
+ func shouldAdoptNativeTextStorageMutation(
17
+ _ mutation: NativeTextMutation,
18
+ allowAfterBlur: Bool = false
19
+ ) -> Bool {
20
+ if isFirstResponder && isEditable {
21
+ return true
22
+ }
23
+ return allowAfterBlur
24
+ && mutation.capturedAfterBlur
25
+ && mutation.inputGeneration == nativeTextMutationGeneration
26
+ && canAdoptNativeTextMutationAfterBlur()
27
+ && mutation.capturedWhileFirstResponder
28
+ && mutation.capturedWhileEditable
29
+ }
30
+
31
+ func canAdoptNativeTextMutationAfterBlur() -> Bool {
32
+ guard let deadline = nativeTextMutationAfterBlurDeadline else {
33
+ return false
34
+ }
35
+ guard nativeTextMutationAfterBlurGeneration == nativeTextMutationGeneration else {
36
+ clearNativeTextMutationAfterBlurWindow()
37
+ return false
38
+ }
39
+ guard ProcessInfo.processInfo.systemUptime <= deadline else {
40
+ clearNativeTextMutationAfterBlurWindow()
41
+ return false
42
+ }
43
+ return true
44
+ }
45
+
46
+ func clearNativeTextMutationAfterBlurWindow() {
47
+ nativeTextMutationAfterBlurDeadline = nil
48
+ nativeTextMutationAfterBlurGeneration = nil
49
+ }
50
+
51
+ private func advanceNativeTextMutationGeneration() {
52
+ nativeTextMutationGeneration &+= 1
53
+ clearNativeTextMutationAfterBlurWindow()
54
+ }
55
+
56
+ func resetPendingNativeTextMutationState() {
57
+ pendingNativeTextMutation = nil
58
+ nativeTextMutationCommitScheduled = false
59
+ advanceNativeTextMutationGeneration()
60
+ }
61
+
62
+ @discardableResult
63
+ func cancelExternalTextCompositionForLifecycleIfNeeded() -> String? {
64
+ finishExternalTextComposition(
65
+ cause: "lifecycle",
66
+ finalText: nil,
67
+ cancel: true
68
+ )?.resultJSON
69
+ }
70
+
71
+ func discardTransientNativeInputForEditorReset() {
72
+ _ = finishExternalTextComposition(cause: "documentChange", finalText: nil, cancel: true)
73
+ deferredInsertTexts.removeAll()
74
+ deferredInsertDrainScheduled = false
75
+ isReplayingDeferredInsertText = false
76
+ resetPendingNativeTextMutationState()
77
+ clearPendingInputTraitRetry()
78
+ performTransientTextMutation {
79
+ super.unmarkText()
80
+ }
81
+ clearMarkedTextTracking()
82
+ }
83
+
84
+ @discardableResult
85
+ func discardTransientNativeInputForEditorRebind() -> String? {
86
+ localTextDragState = .idle
87
+ let externalCompositionResultJSON =
88
+ cancelExternalTextCompositionForLifecycleIfNeeded()
89
+ deferredInsertTexts.removeAll()
90
+ deferredInsertDrainScheduled = false
91
+ isReplayingDeferredInsertText = false
92
+ resetPendingNativeTextMutationState()
93
+ lastAuthorizedSelectedUtf16Range = nil
94
+ lastAuthorizedSelectionIsBackward = false
95
+ logicalSelectionScalarRange = nil
96
+ logicalSelectionUtf16Range = nil
97
+ clearPendingInputTraitRetry()
98
+ markedTextReplacementScalarRange = nil
99
+ markedTextReplacementUtf16Range = nil
100
+ markedTextCompositionText = nil
101
+ markedTextCompositionIsExplicitlyEmpty = false
102
+ isComposing = false
103
+ return externalCompositionResultJSON
104
+ }
105
+
106
+ @discardableResult
107
+ func flushPendingNativeTextMutationCommitIfNeeded() -> Bool {
108
+ drainPendingNativeTextMutation(
109
+ allowAfterBlur: false,
110
+ allowWhileIntercepting: true
111
+ ).ready
112
+ }
113
+
114
+ struct ExternalEditorUpdatePreparation {
115
+ let ready: Bool
116
+ /// When preflight committed local UIKit state, the adapter already
117
+ /// rendered and adopted this current atomic update. Reuse it instead
118
+ /// of reading Rust again for the same external update operation.
119
+ let adoptedUpdateJSON: String?
120
+ }
121
+
122
+ private struct ActiveCompositionPreparation {
123
+ let ready: Bool
124
+ let adoptedUpdateJSON: String?
125
+ }
126
+
127
+ @discardableResult
128
+ func prepareForExternalEditorUpdate() -> Bool {
129
+ prepareForExternalEditorUpdateResult().ready
130
+ }
131
+
132
+ func prepareForExternalEditorUpdateResult() -> ExternalEditorUpdatePreparation {
133
+ let composition = prepareActiveCompositionForExternalMutation()
134
+ guard composition.ready else {
135
+ return ExternalEditorUpdatePreparation(ready: false, adoptedUpdateJSON: nil)
136
+ }
137
+ let nativeMutation = drainPendingNativeTextMutation(
138
+ allowAfterBlur: true,
139
+ allowWhileIntercepting: true
140
+ )
141
+ return ExternalEditorUpdatePreparation(
142
+ ready: nativeMutation.ready,
143
+ adoptedUpdateJSON: composition.adoptedUpdateJSON ?? nativeMutation.adoptedUpdateJSON
144
+ )
145
+ }
146
+
147
+ struct ExternalEditorCommandPreparation {
148
+ let ready: Bool
149
+ let updateJSON: String?
150
+ let blockedReason: String?
151
+ }
152
+
153
+ @discardableResult
154
+ func prepareForExternalEditorCommand() -> ExternalEditorCommandPreparation {
155
+ let previousEditorId = editorId
156
+ let previousAuthorizedText = lastAuthorizedText
157
+ let previousStateJSON = previousEditorId != 0 ? EditorV2Shadow.getCurrentState(id: previousEditorId) : nil
158
+ let preparation = prepareForExternalEditorUpdateResult()
159
+ guard preparation.ready else {
160
+ return ExternalEditorCommandPreparation(ready: false, updateJSON: nil, blockedReason: "composition")
161
+ }
162
+ guard editorId != 0 else {
163
+ return ExternalEditorCommandPreparation(ready: true, updateJSON: nil, blockedReason: nil)
164
+ }
165
+ if let adoptedUpdateJSON = preparation.adoptedUpdateJSON {
166
+ return ExternalEditorCommandPreparation(ready: true, updateJSON: adoptedUpdateJSON, blockedReason: nil)
167
+ }
168
+ let currentStateJSON = EditorV2Shadow.getCurrentState(id: editorId)
169
+ guard lastAuthorizedText != previousAuthorizedText
170
+ || previousEditorId != editorId
171
+ || previousStateJSON != currentStateJSON
172
+ else {
173
+ return ExternalEditorCommandPreparation(ready: true, updateJSON: nil, blockedReason: nil)
174
+ }
175
+ return ExternalEditorCommandPreparation(ready: true, updateJSON: currentStateJSON, blockedReason: nil)
176
+ }
177
+
178
+ private func prepareActiveCompositionForExternalMutation() -> ActiveCompositionPreparation {
179
+ if externalTextComposition != nil {
180
+ guard let finished = finishExternalTextComposition(
181
+ cause: "documentChange",
182
+ finalText: nil,
183
+ cancel: false
184
+ ) else {
185
+ return ActiveCompositionPreparation(ready: false, adoptedUpdateJSON: nil)
186
+ }
187
+ return ActiveCompositionPreparation(
188
+ ready: finished.succeeded,
189
+ adoptedUpdateJSON: finished.adoptedUpdateJSON
190
+ )
191
+ }
192
+ guard isComposing else {
193
+ return ActiveCompositionPreparation(ready: true, adoptedUpdateJSON: nil)
194
+ }
195
+
196
+ let composedText = validatedTrackedMarkedTextForCommit()
197
+ let replacementRange = trackedMarkedTextReplacementRange()
198
+ finishTransientMarkedTextMutation()
199
+
200
+ guard shouldCommitMarkedText(composedText, replacementRange: replacementRange) else {
201
+ restoreAuthorizedTextAfterCancelledCompositionIfNeeded()
202
+ return ActiveCompositionPreparation(ready: false, adoptedUpdateJSON: nil)
203
+ }
204
+
205
+ return ActiveCompositionPreparation(
206
+ ready: true,
207
+ adoptedUpdateJSON: commitMarkedText(composedText ?? "", replacementRange: replacementRange)
208
+ )
209
+ }
210
+
211
+ @discardableResult
212
+ func drainPendingNativeTextMutation(
213
+ allowAfterBlur: Bool,
214
+ allowWhileIntercepting: Bool
215
+ ) -> NativeTextMutationDrainResult {
216
+ if reconciliationWorkScheduled, textStorage.string != lastAuthorizedText {
217
+ let adoptedUpdateJSON = restoreRejectedNativeTextMutation()
218
+ return NativeTextMutationDrainResult(
219
+ ready: textStorage.string == lastAuthorizedText,
220
+ adoptedUpdateJSON: adoptedUpdateJSON
221
+ )
222
+ }
223
+ guard nativeTextMutationCommitScheduled
224
+ || pendingNativeTextMutation != nil
225
+ || (!isComposing && markedTextRange == nil && textStorage.string != lastAuthorizedText)
226
+ else {
227
+ return NativeTextMutationDrainResult(ready: true, adoptedUpdateJSON: nil)
228
+ }
229
+
230
+ nativeTextMutationCommitScheduled = false
231
+ let currentText = textStorage.string
232
+ let mutation: NativeTextMutation?
233
+ if let pendingNativeTextMutation,
234
+ pendingNativeTextMutation.resultingText == currentText,
235
+ pendingNativeTextMutation.authorizedText == lastAuthorizedText {
236
+ mutation = nativeTextMutationWithCurrentSelection(pendingNativeTextMutation)
237
+ } else {
238
+ mutation = nativeTextMutationFromAuthorizedDiff(currentText: currentText)
239
+ }
240
+
241
+ guard let mutation else {
242
+ pendingNativeTextMutation = nil
243
+ return NativeTextMutationDrainResult(ready: true, adoptedUpdateJSON: nil)
244
+ }
245
+
246
+ switch commitNativeTextMutationIfPossible(
247
+ mutation,
248
+ allowAfterBlur: allowAfterBlur,
249
+ allowWhileIntercepting: allowWhileIntercepting
250
+ ) {
251
+ case .committed(let adoptedUpdateJSON):
252
+ pendingNativeTextMutation = nil
253
+ return NativeTextMutationDrainResult(ready: true, adoptedUpdateJSON: adoptedUpdateJSON)
254
+ case .rejected:
255
+ pendingNativeTextMutation = nil
256
+ let adoptedUpdateJSON = restoreRejectedNativeTextMutation()
257
+ return NativeTextMutationDrainResult(
258
+ ready: textStorage.string == lastAuthorizedText,
259
+ adoptedUpdateJSON: adoptedUpdateJSON
260
+ )
261
+ case .deferred:
262
+ pendingNativeTextMutation = mutation
263
+ return NativeTextMutationDrainResult(ready: false, adoptedUpdateJSON: nil)
264
+ }
265
+ }
266
+
267
+ private func restoreRejectedNativeTextMutation() -> String? {
268
+ guard editorId != 0, textStorage.string != lastAuthorizedText else { return nil }
269
+ reconciliationWorkScheduled = false
270
+ let updateJSON = EditorV2Shadow.getCurrentState(id: editorId)
271
+ return applyUpdateJSON(updateJSON) ? updateJSON : nil
272
+ }
273
+
274
+ func scheduleNativeTextMutationCommit(_ mutation: NativeTextMutation) {
275
+ pendingNativeTextMutation = mutation
276
+ guard !nativeTextMutationCommitScheduled else { return }
277
+
278
+ nativeTextMutationCommitScheduled = true
279
+ DispatchQueue.main.async { [weak self] in
280
+ guard let self else { return }
281
+ _ = self.drainPendingNativeTextMutation(
282
+ allowAfterBlur: true,
283
+ allowWhileIntercepting: true
284
+ )
285
+ }
286
+ }
287
+
288
+ @discardableResult
289
+ func commitNativeTextMutationIfPossible(
290
+ _ mutation: NativeTextMutation,
291
+ allowAfterBlur: Bool,
292
+ allowWhileIntercepting: Bool
293
+ ) -> NativeTextMutationCommitResult {
294
+ guard editorId != 0 else {
295
+ return .rejected
296
+ }
297
+
298
+ guard !isApplyingRustState,
299
+ !isInterceptingInput || allowWhileIntercepting,
300
+ !isComposing
301
+ else {
302
+ return .deferred
303
+ }
304
+
305
+ guard shouldAdoptNativeTextStorageMutation(mutation, allowAfterBlur: allowAfterBlur) else {
306
+ if textStorage.string != lastAuthorizedText {
307
+ scheduleReconciliationFromRust()
308
+ }
309
+ return .rejected
310
+ }
311
+
312
+ guard textStorage.string == mutation.resultingText else {
313
+ if let refreshedMutation = nativeTextMutationFromAuthorizedDiff(currentText: textStorage.string) {
314
+ return commitNativeTextMutationIfPossible(
315
+ refreshedMutation,
316
+ allowAfterBlur: allowAfterBlur,
317
+ allowWhileIntercepting: allowWhileIntercepting
318
+ )
319
+ }
320
+ return .rejected
321
+ }
322
+
323
+ guard mutation.authorizedText == lastAuthorizedText else {
324
+ if let refreshedMutation = nativeTextMutationFromAuthorizedDiff(currentText: textStorage.string) {
325
+ return commitNativeTextMutationIfPossible(
326
+ refreshedMutation,
327
+ allowAfterBlur: allowAfterBlur,
328
+ allowWhileIntercepting: allowWhileIntercepting
329
+ )
330
+ }
331
+ return .rejected
332
+ }
333
+
334
+ var adoptedUpdateJSON: String?
335
+ performInterceptedInput(flushPendingNativeTextMutation: false) {
336
+ guard let adapter = EditorV2Registry.adapter(forLegacyId: editorId) else { return }
337
+ let postSelection: (anchor: UInt32, head: UInt32)?
338
+ if let anchor = mutation.selectionAnchor,
339
+ let head = mutation.selectionHead {
340
+ postSelection = (anchor: anchor, head: head)
341
+ } else {
342
+ postSelection = nil
343
+ }
344
+ adoptedUpdateJSON = adapter.commitNativeTextMutation(
345
+ from: mutation.from,
346
+ to: mutation.to,
347
+ with: mutation.replacementText,
348
+ postSelection: postSelection
349
+ )
350
+ guard let adoptedUpdateJSON else { return }
351
+ applyUpdateJSON(adoptedUpdateJSON)
352
+ notifyDelegateOfAuthoritativeTextSelection()
353
+ }
354
+ guard let adoptedUpdateJSON else { return .rejected }
355
+ if mutation.capturedAfterBlur {
356
+ clearNativeTextMutationAfterBlurWindow()
357
+ }
358
+ return .committed(adoptedUpdateJSON: adoptedUpdateJSON)
359
+ }
360
+
361
+ private func notifyDelegateOfAuthoritativeTextSelection() {
362
+ guard editorId != 0,
363
+ let selection = logicalSelectionScalarRange
364
+ else {
365
+ return
366
+ }
367
+ let docAnchor = EditorV2Shadow.scalarToDoc(id: editorId, scalar: selection.anchor)
368
+ let docHead = EditorV2Shadow.scalarToDoc(id: editorId, scalar: selection.head)
369
+ editorDelegate?.editorTextView(self, selectionDidChange: docAnchor, head: docHead)
370
+ }
371
+
372
+ }