@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,281 @@
1
+ package com.apollohg.editor
2
+
3
+ import android.text.Spanned
4
+ import org.json.JSONObject
5
+
6
+ /**
7
+ * Insert text at a scalar position via the Rust editor.
8
+ */
9
+ internal fun EditorEditText.insertTextInRust(text: String, atScalarPos: Int) {
10
+ if (!hasLiveEditor()) return
11
+ onInsertTextInRustForTesting?.let { callback ->
12
+ callback(text, atScalarPos)
13
+ return
14
+ }
15
+ v2Driver?.let { driver ->
16
+ driver.insertText(text, atScalarPos)?.let { applyRustUpdateJSON(it) }
17
+ }
18
+ }
19
+
20
+ internal fun EditorEditText.replaceTextRangeInRust(
21
+ scalarFrom: Int,
22
+ scalarTo: Int,
23
+ text: String
24
+ ): Boolean {
25
+ if (!hasLiveEditor()) return false
26
+ onReplaceTextInRustForTesting?.let { callback ->
27
+ callback(scalarFrom, scalarTo, text)
28
+ return true
29
+ }
30
+ val update = v2Driver?.replaceTextRange(scalarFrom, scalarTo, text) ?: return false
31
+ applyRustUpdateJSON(update)
32
+ return true
33
+ }
34
+
35
+ internal fun EditorEditText.insertPlainTextRangeInRust(
36
+ scalarFrom: Int,
37
+ scalarTo: Int,
38
+ text: String,
39
+ requestedCursorScalar: Int? = null
40
+ ) {
41
+ if (!hasLiveEditor()) return
42
+ recordImeTraceForTesting(
43
+ "rustPlainTextRoute",
44
+ "range=$scalarFrom..$scalarTo textLength=${text.length} requestedCursor=$requestedCursorScalar"
45
+ )
46
+ if (text.isEmpty()) {
47
+ if (scalarFrom != scalarTo) {
48
+ deleteRangeInRust(scalarFrom, scalarTo)
49
+ }
50
+ applyRequestedCursorScalar(requestedCursorScalar)
51
+ return
52
+ }
53
+ if (text.indexOf('\n') >= 0 || text.indexOf('\r') >= 0) {
54
+ if (!replaceTextRangeInRust(scalarFrom, scalarTo, text)) {
55
+ restoreAuthorizedTextSnapshotForEditor()
56
+ return
57
+ }
58
+ applyRequestedCursorScalar(requestedCursorScalar)
59
+ return
60
+ }
61
+
62
+ if (scalarFrom != scalarTo) {
63
+ replaceTextRangeInRust(scalarFrom, scalarTo, text)
64
+ } else {
65
+ insertTextInRust(text, scalarFrom)
66
+ }
67
+ applyRequestedCursorScalar(requestedCursorScalar)
68
+ }
69
+
70
+ internal fun EditorEditText.requestedCursorScalar(
71
+ scalarFrom: Int,
72
+ scalarTo: Int,
73
+ currentText: String,
74
+ insertedText: String,
75
+ newCursorPosition: Int
76
+ ): Int? {
77
+ if (newCursorPosition == 1) return null
78
+ val rawStart = PositionBridge.scalarToUtf16(scalarFrom, currentText)
79
+ val inCodeBlock =
80
+ (text as? Spanned)?.getSpans(rawStart, rawStart, CodeBlockSpan::class.java)?.isNotEmpty() ==
81
+ true
82
+ val effectiveText = if (inCodeBlock) {
83
+ insertedText
84
+ } else {
85
+ insertedText.replace(
86
+ "\r\n",
87
+ "\n"
88
+ ).replace('\r', '\n')
89
+ }
90
+ val insertedScalarLength = effectiveText.codePointCount(0, effectiveText.length)
91
+ val currentScalarLength = currentText.codePointCount(0, currentText.length)
92
+ val nextScalarLength =
93
+ (currentScalarLength - (scalarTo - scalarFrom) + insertedScalarLength).coerceAtLeast(0)
94
+ val requested = if (newCursorPosition > 0) {
95
+ scalarFrom + insertedScalarLength + newCursorPosition - 1
96
+ } else {
97
+ scalarFrom + newCursorPosition
98
+ }
99
+ return requested.coerceIn(0, nextScalarLength)
100
+ }
101
+
102
+ internal fun EditorEditText.applyRequestedCursorScalar(requestedCursorScalar: Int?) {
103
+ val requested = requestedCursorScalar ?: return
104
+ if (!hasLiveEditor()) return
105
+ val safeScalar = requested.coerceAtLeast(0)
106
+ val cursorDriver = v2Driver
107
+ if (cursorDriver != null) {
108
+ cursorDriver.syncSelectionQuiet(safeScalar, safeScalar)?.let(::applyRustUpdateJSON)
109
+ } else {
110
+ onSetSelectionScalarInRustForTesting?.let { callback ->
111
+ callback(safeScalar, safeScalar)
112
+ }
113
+ }
114
+ val currentText = text?.toString().orEmpty()
115
+ val localScalar = safeScalar.coerceIn(0, currentText.codePointCount(0, currentText.length))
116
+ val safeUtf16 = PositionBridge.scalarToUtf16(localScalar, currentText)
117
+ .coerceIn(0, currentText.length)
118
+ if (selectionStart != safeUtf16 || selectionEnd != safeUtf16) {
119
+ setSelection(safeUtf16, safeUtf16)
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Delete a scalar range via the Rust editor.
125
+ *
126
+ * @param scalarFrom Start scalar offset (inclusive).
127
+ * @param scalarTo End scalar offset (exclusive).
128
+ */
129
+ internal fun EditorEditText.deleteRangeInRust(scalarFrom: Int, scalarTo: Int) {
130
+ if (!hasLiveEditor()) return
131
+ if (scalarFrom >= scalarTo) return
132
+ onDeleteRangeInRustForTesting?.let { callback ->
133
+ callback(scalarFrom, scalarTo)
134
+ return
135
+ }
136
+ v2Driver?.let { driver ->
137
+ driver.deleteScalarRange(scalarFrom, scalarTo)?.let { applyRustUpdateJSON(it) }
138
+ }
139
+ }
140
+
141
+ internal fun EditorEditText.deleteBackwardAtSelectionScalarInRust(
142
+ scalarAnchor: Int,
143
+ scalarHead: Int
144
+ ) {
145
+ if (!hasLiveEditor()) return
146
+ onDeleteBackwardAtSelectionScalarInRustForTesting?.let { callback ->
147
+ callback(scalarAnchor, scalarHead)
148
+ return
149
+ }
150
+ v2Driver?.let { driver ->
151
+ if (selectAtomBeforeEmptyTrailingParagraph(driver)) return
152
+ driver.deleteBackwardAtSelection(scalarAnchor, scalarHead)?.let { applyRustUpdateJSON(it) }
153
+ }
154
+ }
155
+
156
+ internal fun EditorEditText.toggleTaskItemCheckedAtSelectionScalarInRust(
157
+ scalarAnchor: Int,
158
+ scalarHead: Int
159
+ ) {
160
+ if (!hasLiveEditor()) return
161
+ onToggleTaskItemCheckedAtSelectionScalarInRustForTesting?.let { callback ->
162
+ callback(scalarAnchor, scalarHead)
163
+ return
164
+ }
165
+ v2Driver?.let { driver ->
166
+ val selection =
167
+ currentLogicalScalarSelection() ?: rawScalarSelection(text?.toString().orEmpty())
168
+ driver.toggleTaskItemCheckedAtSelection(scalarAnchor, scalarHead)?.let { update ->
169
+ applyRustUpdateJSON(update)
170
+ if (selection != null) {
171
+ driver.syncSelectionQuiet(
172
+ selection.first,
173
+ selection.second
174
+ )?.let(::applyRustUpdateJSON)
175
+ val currentText = text?.toString().orEmpty()
176
+ setSelection(
177
+ PositionBridge.scalarToUtf16(selection.first, currentText),
178
+ PositionBridge.scalarToUtf16(selection.second, currentText)
179
+ )
180
+ }
181
+ }
182
+ }
183
+ }
184
+
185
+ /**
186
+ * Split a block at a scalar position via the Rust editor.
187
+ */
188
+ internal fun EditorEditText.splitBlockInRust(atScalarPos: Int) {
189
+ if (!hasLiveEditor()) return
190
+ onSplitBlockInRustForTesting?.let { callback ->
191
+ callback(atScalarPos)
192
+ return
193
+ }
194
+ v2Driver?.let { driver ->
195
+ driver.splitBlockAt(atScalarPos)?.let { result ->
196
+ applyRustUpdateJSON(
197
+ result.updateJson,
198
+ lineBoundaryRefreshSource = if (result.committed) "splitBlock" else null
199
+ )
200
+ }
201
+ }
202
+ }
203
+
204
+ internal fun EditorEditText.deleteAndSplitInRust(scalarFrom: Int, scalarTo: Int) {
205
+ if (!hasLiveEditor()) return
206
+ onDeleteAndSplitScalarInRustForTesting?.let { callback ->
207
+ callback(scalarFrom, scalarTo)
208
+ return
209
+ }
210
+ v2Driver?.let { driver ->
211
+ driver.deleteAndSplit(scalarFrom, scalarTo)?.let { result ->
212
+ applyRustUpdateJSON(
213
+ result.updateJson,
214
+ lineBoundaryRefreshSource = if (result.committed) "deleteAndSplit" else null
215
+ )
216
+ }
217
+ }
218
+ }
219
+
220
+ internal fun EditorEditText.isSelectionInsideList(): Boolean {
221
+ if (!hasLiveEditor()) return false
222
+
223
+ return try {
224
+ val stateJson = v2Driver?.currentStateJson() ?: return false
225
+ val state = org.json.JSONObject(stateJson)
226
+ val nodes = state.optJSONObject("activeState")?.optJSONObject("nodes")
227
+ nodes?.keys()?.asSequence()?.any { nodeType ->
228
+ EditorNodeTypes.isListContainer(nodeType) && nodes.optBoolean(nodeType, false)
229
+ } == true
230
+ } catch (_: Exception) {
231
+ false
232
+ }
233
+ }
234
+
235
+ internal fun EditorEditText.preferredHardBreakNodeType(): String {
236
+ return try {
237
+ val stateJson = v2Driver?.currentStateJson() ?: return "hardBreak"
238
+ val insertableNodes = org.json.JSONObject(stateJson)
239
+ .optJSONObject("activeState")
240
+ ?.optJSONArray("insertableNodes")
241
+ val names = buildSet {
242
+ if (insertableNodes != null) {
243
+ for (index in 0 until insertableNodes.length()) {
244
+ insertableNodes.optString(index, null)?.let(::add)
245
+ }
246
+ }
247
+ }
248
+ EditorNodeTypes.preferredHardBreak(names)
249
+ } catch (_: Exception) {
250
+ "hardBreak"
251
+ }
252
+ }
253
+
254
+ /**
255
+ * Paste HTML content through Rust.
256
+ */
257
+ internal fun EditorEditText.pasteHTML(html: String) {
258
+ if (!hasLiveEditor()) return
259
+ syncCurrentSelectionToRust()
260
+ onInsertContentHtmlInRustForTesting?.let { callback ->
261
+ callback(html)
262
+ return
263
+ }
264
+ v2Driver?.let { driver ->
265
+ val selection = currentScalarSelection()
266
+ val update = if (selection != null) {
267
+ driver.insertContentHtmlAtSelection(html, selection.first, selection.second)
268
+ } else {
269
+ null
270
+ }
271
+ update?.let { applyUpdateJSON(it) }
272
+ }
273
+ }
274
+
275
+ /**
276
+ * Paste plain text through Rust.
277
+ */
278
+ internal fun EditorEditText.pastePlainText(text: String) {
279
+ val (scalarStart, scalarEnd) = currentScalarSelection() ?: return
280
+ insertPlainTextRangeInRust(scalarStart, scalarEnd, text)
281
+ }
@@ -0,0 +1,352 @@
1
+ package com.apollohg.editor
2
+
3
+ import android.graphics.RectF
4
+ import android.text.Annotation
5
+ import android.text.Selection
6
+ import android.text.Spanned
7
+ import org.json.JSONObject
8
+
9
+ internal fun EditorEditText.caretRectImpl(): RectF? {
10
+ if (isCollapsedAtomBoundarySelection(selectionStart, selectionEnd)) return null
11
+ val textLayout = layout ?: return null
12
+ val selectionOffset = selectionEnd.takeIf { it >= 0 } ?: return null
13
+ val clampedOffset = selectionOffset.coerceIn(0, textLayout.text.length)
14
+ val caretLeft = textLayout.getPrimaryHorizontal(clampedOffset)
15
+ // Clip the caret to the rendered glyph height so a ParagraphSpacerSpan's
16
+ // inflated descent does not stretch it into the inter-block gap.
17
+ val bounds = CaretGeometry.verticalBounds(
18
+ textLayout,
19
+ clampedOffset,
20
+ paint,
21
+ textLayout.text
22
+ )
23
+ val left = totalPaddingLeft + caretLeft - scrollX
24
+ val top = totalPaddingTop + bounds.top - scrollY
25
+ val bottom = totalPaddingTop + bounds.bottom - scrollY
26
+ return RectF(left, top, left + 1f, bottom)
27
+ }
28
+
29
+ internal fun EditorEditText.isCollapsedAtomBoundarySelection(start: Int, end: Int): Boolean {
30
+ if (start != end) return false
31
+ val content = text as? Spanned ?: return false
32
+ if (start < 0 || start > content.length) return false
33
+ if (start < content.length) {
34
+ val beginsWithAtom = content
35
+ .getSpans(start, start + 1, AtomBlockSpan::class.java)
36
+ .any { content.getSpanStart(it) == start }
37
+ if (beginsWithAtom) return true
38
+ }
39
+ if (start > 0) {
40
+ return content
41
+ .getSpans(start - 1, start, AtomBlockSpan::class.java)
42
+ .any { content.getSpanEnd(it) == start }
43
+ }
44
+ return false
45
+ }
46
+
47
+ internal fun EditorEditText.updateAtomBoundaryCursorVisibility() {
48
+ val shouldShowCursor = !isCollapsedAtomBoundarySelection(selectionStart, selectionEnd)
49
+ if (isCursorVisible != shouldShowCursor) {
50
+ isCursorVisible = shouldShowCursor
51
+ invalidate()
52
+ }
53
+ }
54
+
55
+ internal fun EditorEditText.restoreSelectionFromAtomBoundaryIfNeeded(
56
+ start: Int,
57
+ end: Int
58
+ ): Boolean {
59
+ if (!isCollapsedAtomBoundarySelection(start, end)) {
60
+ if (start >= 0 && end >= 0) {
61
+ lastAllowedAtomCaretSelection = start to end
62
+ }
63
+ updateAtomBoundaryCursorVisibility()
64
+ return false
65
+ }
66
+
67
+ updateAtomBoundaryCursorVisibility()
68
+ if (!isApplyingRustState) {
69
+ val editable = text
70
+ val allowed = lastAllowedAtomCaretSelection
71
+ if (
72
+ editable != null &&
73
+ allowed != null &&
74
+ allowed.first in 0..editable.length &&
75
+ allowed.second in 0..editable.length &&
76
+ !isCollapsedAtomBoundarySelection(allowed.first, allowed.second)
77
+ ) {
78
+ runWithTransientInputMutationGuard {
79
+ Selection.setSelection(editable, allowed.first, allowed.second)
80
+ true
81
+ }
82
+ }
83
+ }
84
+ return true
85
+ }
86
+
87
+ internal fun EditorEditText.canonicalListCaretOffset(selStart: Int, selEnd: Int): Int? {
88
+ if (selStart != selEnd) return null
89
+ val content = text as? Spanned ?: return null
90
+ if (selStart !in 0 until content.length) return null
91
+ return content
92
+ .getSpans(selStart, selStart + 1, Annotation::class.java)
93
+ .firstOrNull { annotation ->
94
+ annotation.key == RenderBridge.NATIVE_LIST_MARKER_ANNOTATION &&
95
+ content.getSpanStart(annotation) <= selStart &&
96
+ content.getSpanEnd(annotation) > selStart
97
+ }
98
+ ?.let(content::getSpanEnd)
99
+ }
100
+
101
+ internal fun EditorEditText.syncCurrentSelectionToRust() {
102
+ if (!hasLiveEditor()) return
103
+
104
+ val currentText = text?.toString() ?: ""
105
+ if (currentText != lastAuthorizedText) return
106
+ val (scalarAnchor, scalarHead) = currentLogicalScalarSelection()
107
+ ?: rawScalarSelection(currentText)
108
+ ?: return
109
+
110
+ v2Driver?.let { driver ->
111
+ val sync = driver.syncSelection(scalarAnchor, scalarHead)
112
+ if (sync != null) {
113
+ sync.refreshedUpdateJson?.let { applyRustUpdateJSON(it) }
114
+ editorListener?.onSelectionChanged(sync.docAnchor, sync.docHead)
115
+ }
116
+ return
117
+ }
118
+ onSetSelectionScalarInRustForTesting?.invoke(scalarAnchor, scalarHead)
119
+ }
120
+
121
+ internal fun EditorEditText.currentScalarSelectionImpl(): Pair<Int, Int>? {
122
+ currentLogicalScalarSelection()?.let { return it }
123
+ val currentText = text?.toString() ?: return null
124
+ return normalizedScalarSelectionRange(currentText)
125
+ }
126
+
127
+ internal fun EditorEditText.currentLogicalScalarSelectionForInputImpl(): Pair<Int, Int>? =
128
+ currentLogicalScalarSelection()
129
+
130
+ internal fun EditorEditText.renderedRangeContainsGeneratedStructureImpl(
131
+ start: Int,
132
+ endExclusive: Int
133
+ ): Boolean {
134
+ if (start >= endExclusive) return false
135
+ val content = text as? Spanned ?: return false
136
+ return content.getSpans(start, endExclusive, Annotation::class.java).any { annotation ->
137
+ isGeneratedStructureAnnotation(annotation)
138
+ }
139
+ }
140
+
141
+ internal fun EditorEditText.compositionContentRangeForEditorImpl(
142
+ start: Int,
143
+ end: Int
144
+ ): Pair<Int, Int>? {
145
+ val content = text as? Spanned ?: return null
146
+ var contentStart = minOf(start, end).coerceIn(0, content.length)
147
+ var contentEnd = maxOf(start, end).coerceIn(0, content.length)
148
+ val generatedSpans = content
149
+ .getSpans(0, content.length, Annotation::class.java)
150
+ .filter(::isGeneratedStructureAnnotation)
151
+
152
+ var changed: Boolean
153
+ do {
154
+ changed = false
155
+ generatedSpans.forEach { annotation ->
156
+ val spanStart = content.getSpanStart(annotation)
157
+ val spanEnd = content.getSpanEnd(annotation)
158
+ if (spanStart <= contentStart && spanEnd > contentStart && spanEnd <= contentEnd) {
159
+ contentStart = spanEnd
160
+ changed = true
161
+ }
162
+ if (spanStart >= contentStart && spanStart < contentEnd && spanEnd >= contentEnd) {
163
+ contentEnd = spanStart
164
+ changed = true
165
+ }
166
+ }
167
+ } while (changed)
168
+
169
+ val containsInteriorStructure = generatedSpans.any { annotation ->
170
+ content.getSpanStart(annotation) < contentEnd &&
171
+ content.getSpanEnd(annotation) > contentStart
172
+ }
173
+ if (containsInteriorStructure) return null
174
+ return contentStart to contentEnd
175
+ }
176
+
177
+ internal fun EditorEditText.isGeneratedStructureAnnotation(annotation: Annotation): Boolean =
178
+ annotation.key == RenderBridge.NATIVE_INTER_BLOCK_SEPARATOR_ANNOTATION ||
179
+ annotation.key == RenderBridge.NATIVE_LIST_MARKER_ANNOTATION ||
180
+ annotation.key == RenderBridge.NATIVE_SYNTHETIC_PLACEHOLDER_ANNOTATION
181
+
182
+ internal fun EditorEditText.normalizedUtf16SelectionRange(currentText: String): Pair<Int, Int>? {
183
+ val start = selectionStart
184
+ val end = selectionEnd
185
+ if (start < 0 || end < 0) return null
186
+ val clampedStart = start.coerceIn(0, currentText.length)
187
+ val clampedEnd = end.coerceIn(0, currentText.length)
188
+ return minOf(clampedStart, clampedEnd) to maxOf(clampedStart, clampedEnd)
189
+ }
190
+
191
+ internal fun EditorEditText.normalizedUtf16SelectionRange(): Pair<Int, Int>? {
192
+ val currentText = text?.toString() ?: return null
193
+ return normalizedUtf16SelectionRange(currentText)
194
+ }
195
+
196
+ internal fun EditorEditText.normalizedScalarSelectionRange(currentText: String): Pair<Int, Int>? {
197
+ currentLogicalScalarSelection()?.let { (anchor, head) ->
198
+ return minOf(anchor, head) to maxOf(anchor, head)
199
+ }
200
+ val (start, end) = normalizedUtf16SelectionRange(currentText) ?: return null
201
+ val (snappedStart, snappedEnd) = if (start == end) {
202
+ val snapped = PositionBridge.snapToScalarBoundary(
203
+ start,
204
+ currentText,
205
+ biasForward = true
206
+ )
207
+ snapped to snapped
208
+ } else {
209
+ PositionBridge.snapRangeToScalarBoundaries(start, end, currentText)
210
+ }
211
+ return PositionBridge.utf16ToScalar(snappedStart, currentText) to
212
+ PositionBridge.utf16ToScalar(snappedEnd, currentText)
213
+ }
214
+
215
+ internal fun EditorEditText.currentLogicalScalarSelection(): Pair<Int, Int>? {
216
+ val snapshot = logicalSelectionSnapshot ?: return null
217
+ if (selectionStart == snapshot.utf16Anchor && selectionEnd == snapshot.utf16Head) {
218
+ return snapshot.scalarAnchor to snapshot.scalarHead
219
+ }
220
+ recordImeTraceForTesting(
221
+ "logicalSelectionInvalidated",
222
+ "scalar=${snapshot.scalarAnchor}..${snapshot.scalarHead} projected=${snapshot.utf16Anchor}..${snapshot.utf16Head} physical=$selectionStart..$selectionEnd revision=${snapshot.documentVersion ?: "pending"}"
223
+ )
224
+ logicalSelectionSnapshot = null
225
+ return null
226
+ }
227
+
228
+ internal fun EditorEditText.rememberLogicalSelection(
229
+ scalarAnchor: Int,
230
+ scalarHead: Int,
231
+ utf16Anchor: Int,
232
+ utf16Head: Int,
233
+ documentVersion: String? = logicalSelectionSnapshot?.documentVersion
234
+ ) {
235
+ logicalSelectionSnapshot = LogicalSelectionSnapshot(
236
+ scalarAnchor = scalarAnchor,
237
+ scalarHead = scalarHead,
238
+ utf16Anchor = utf16Anchor,
239
+ utf16Head = utf16Head,
240
+ documentVersion = documentVersion
241
+ )
242
+ }
243
+
244
+ internal fun EditorEditText.rawScalarSelection(currentText: String): Pair<Int, Int>? {
245
+ val anchor = selectionStart
246
+ val head = selectionEnd
247
+ if (anchor < 0 || head < 0) return null
248
+ val clampedAnchor = anchor.coerceIn(0, currentText.length)
249
+ val clampedHead = head.coerceIn(0, currentText.length)
250
+ if (clampedAnchor == clampedHead) {
251
+ val snapped = PositionBridge.snapToScalarBoundary(
252
+ clampedAnchor,
253
+ currentText,
254
+ biasForward = true
255
+ )
256
+ val scalar = PositionBridge.utf16ToScalar(snapped, currentText)
257
+ return scalar to scalar
258
+ }
259
+ val (rangeStart, rangeEnd) = PositionBridge.snapRangeToScalarBoundaries(
260
+ minOf(clampedAnchor, clampedHead),
261
+ maxOf(clampedAnchor, clampedHead),
262
+ currentText
263
+ )
264
+ val snappedAnchor = if (clampedAnchor < clampedHead) rangeStart else rangeEnd
265
+ val snappedHead = if (clampedAnchor < clampedHead) rangeEnd else rangeStart
266
+ return PositionBridge.utf16ToScalar(snappedAnchor, currentText) to
267
+ PositionBridge.utf16ToScalar(snappedHead, currentText)
268
+ }
269
+
270
+ /**
271
+ * Apply a selection from a parsed JSON selection object.
272
+ *
273
+ * The selection JSON matches the format from `serialize_editor_update`:
274
+ * ```json
275
+ * {"type": "text", "anchor": 5, "head": 5}
276
+ * {"type": "node", "pos": 10}
277
+ * {"type": "all"}
278
+ * ```
279
+ *
280
+ * anchor/head from Rust are **document positions** (include structural tokens).
281
+ * We convert doc→scalar via the v2 driver ([EditorV2Driver.scalarPositionForDoc])
282
+ * before converting to UTF-16.
283
+ */
284
+ internal fun EditorEditText.applySelectionFromJSON(
285
+ selection: org.json.JSONObject,
286
+ documentVersion: String?
287
+ ) {
288
+ val type = selection.optString("type", "") ?: return
289
+ if (isEditorDestroyedForInput()) {
290
+ recordImeTraceForTesting("applySelectionFromJSONSkipped", "reason=destroyed type=$type")
291
+ return
292
+ }
293
+
294
+ isApplyingRustState = true
295
+ try {
296
+ val currentText = text?.toString() ?: ""
297
+ when (type) {
298
+ "text" -> {
299
+ val docAnchor = exactV2ScalarInt(selection.opt("anchor") as? Number) ?: return
300
+ val docHead = exactV2ScalarInt(selection.opt("head") as? Number) ?: return
301
+ // The frozen v2 update includes exact scalar positions alongside its
302
+ // structural document positions. Prefer those values: a cursor inside
303
+ // an empty trailing block sits at a document boundary that cannot be
304
+ // reconstructed from rendered structural tokens alone.
305
+ val selectionDriver = v2Driver ?: return
306
+ val scalarAnchor = exactV2ScalarInt(selection.opt("anchorScalar") as? Number)
307
+ ?: selectionDriver.scalarPositionForDoc(docAnchor)
308
+ ?: docAnchor
309
+ val scalarHead = exactV2ScalarInt(selection.opt("headScalar") as? Number)
310
+ ?: selectionDriver.scalarPositionForDoc(docHead)
311
+ ?: docHead
312
+ val anchorUtf16 = PositionBridge.scalarToUtf16(scalarAnchor, currentText)
313
+ val headUtf16 = PositionBridge.scalarToUtf16(scalarHead, currentText)
314
+ val len = text?.length ?: 0
315
+ recordImeTraceForTesting(
316
+ "applySelectionFromJSON",
317
+ "doc=$docAnchor..$docHead scalar=$scalarAnchor..$scalarHead utf16=$anchorUtf16..$headUtf16 len=$len"
318
+ )
319
+ setSelection(
320
+ anchorUtf16.coerceIn(0, len),
321
+ headUtf16.coerceIn(0, len)
322
+ )
323
+ rememberLogicalSelection(
324
+ scalarAnchor = scalarAnchor,
325
+ scalarHead = scalarHead,
326
+ utf16Anchor = selectionStart,
327
+ utf16Head = selectionEnd,
328
+ documentVersion = documentVersion
329
+ )
330
+ }
331
+
332
+ "node" -> {
333
+ logicalSelectionSnapshot = null
334
+ val docPos = exactV2ScalarInt(selection.opt("pos") as? Number) ?: return
335
+ val nodeSelectionDriver = v2Driver ?: return
336
+ val scalarPos = nodeSelectionDriver.scalarPositionForDoc(docPos) ?: docPos
337
+ val startUtf16 = PositionBridge.scalarToUtf16(scalarPos, currentText)
338
+ val len = text?.length ?: 0
339
+ val clamped = startUtf16.coerceIn(0, len)
340
+ val endClamped = (clamped + 1).coerceAtMost(len)
341
+ setSelection(clamped, endClamped)
342
+ }
343
+
344
+ "all" -> {
345
+ logicalSelectionSnapshot = null
346
+ selectAll()
347
+ }
348
+ }
349
+ } finally {
350
+ isApplyingRustState = false
351
+ }
352
+ }