@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,314 @@
1
+ package com.apollohg.editor
2
+
3
+ import android.content.Context
4
+ import android.graphics.Canvas
5
+ import android.graphics.Color
6
+ import android.graphics.Paint
7
+ import android.graphics.Path
8
+ import android.graphics.RectF
9
+ import android.util.AttributeSet
10
+ import android.util.TypedValue
11
+ import androidx.appcompat.content.res.AppCompatResources
12
+ import org.json.JSONArray
13
+
14
+ data class RemoteSelectionDecoration(
15
+ val clientId: String,
16
+ val anchor: Int,
17
+ val head: Int,
18
+ val color: Int,
19
+ val name: String?,
20
+ val isFocused: Boolean
21
+ ) {
22
+ companion object {
23
+ fun fromJson(context: Context, json: String?): List<RemoteSelectionDecoration> {
24
+ if (json.isNullOrBlank()) return emptyList()
25
+ val array = try {
26
+ JSONArray(json)
27
+ } catch (_: Throwable) {
28
+ return emptyList()
29
+ }
30
+ val fallbackColor = resolveFallbackColor(context)
31
+
32
+ return buildList {
33
+ for (index in 0 until array.length()) {
34
+ val item = array.optJSONObject(index) ?: continue
35
+ val clientId = canonicalV2U64(item.opt("clientId") as? String) ?: continue
36
+ val anchor = exactV2ScalarInt(item.opt("anchor") as? Number) ?: continue
37
+ val head = exactV2ScalarInt(item.opt("head") as? Number) ?: continue
38
+ val color = parseColor(item.optString("color", ""), fallbackColor)
39
+ add(
40
+ RemoteSelectionDecoration(
41
+ clientId = clientId,
42
+ anchor = anchor,
43
+ head = head,
44
+ color = color,
45
+ name = item.optString("name").takeIf { it.isNotBlank() },
46
+ isFocused = item.optBoolean("isFocused", false)
47
+ )
48
+ )
49
+ }
50
+ }
51
+ }
52
+
53
+ private fun parseColor(raw: String, fallbackColor: Int): Int = try {
54
+ Color.parseColor(raw)
55
+ } catch (_: Throwable) {
56
+ fallbackColor
57
+ }
58
+
59
+ private fun resolveFallbackColor(context: Context): Int {
60
+ val typedValue = TypedValue()
61
+ val attrs = intArrayOf(
62
+ androidx.appcompat.R.attr.colorPrimary,
63
+ androidx.appcompat.R.attr.colorAccent,
64
+ android.R.attr.colorAccent,
65
+ android.R.attr.textColorPrimary
66
+ )
67
+ for (attr in attrs) {
68
+ if (!context.theme.resolveAttribute(attr, typedValue, true)) {
69
+ continue
70
+ }
71
+ if (typedValue.resourceId != 0) {
72
+ AppCompatResources.getColorStateList(context, typedValue.resourceId)
73
+ ?.defaultColor
74
+ ?.let { return it }
75
+ } else if (typedValue.type in
76
+ TypedValue.TYPE_FIRST_COLOR_INT..TypedValue.TYPE_LAST_COLOR_INT
77
+ ) {
78
+ return typedValue.data
79
+ }
80
+ }
81
+ return Color.TRANSPARENT
82
+ }
83
+ }
84
+ }
85
+
86
+ data class RemoteSelectionDebugSnapshot(val clientId: String, val caretRect: RectF?)
87
+
88
+ class RemoteSelectionOverlayView @JvmOverloads constructor(
89
+ context: Context,
90
+ attrs: AttributeSet? = null,
91
+ defStyleAttr: Int = 0
92
+ ) : PointerTransparentView(context, attrs, defStyleAttr) {
93
+ private data class CachedSelectionGeometry(
94
+ val clientId: String,
95
+ val selectionPath: Path?,
96
+ val selectionColor: Int,
97
+ val caretRect: RectF?,
98
+ val caretColor: Int
99
+ )
100
+
101
+ private data class GeometrySnapshot(
102
+ val editorId: Long,
103
+ val text: String,
104
+ val layoutWidth: Int,
105
+ val layoutHeight: Int,
106
+ val baseX: Int,
107
+ val baseY: Int,
108
+ val width: Int,
109
+ val height: Int,
110
+ val selections: List<RemoteSelectionDecoration>
111
+ )
112
+
113
+ private data class GeometryContext(
114
+ val snapshot: GeometrySnapshot,
115
+ val layout: android.text.Layout,
116
+ val caretWidth: Float
117
+ )
118
+
119
+ private var editorView: RichTextEditorView? = null
120
+ private var remoteSelections: List<RemoteSelectionDecoration> = emptyList()
121
+ private var cachedSnapshot: GeometrySnapshot? = null
122
+ private var cachedGeometry: List<CachedSelectionGeometry> = emptyList()
123
+ internal var editorIdOverrideForTesting: Long? = null
124
+ internal var docToScalarResolver: (Long, Int) -> Int = { editorId, docPos ->
125
+ EditorV2Registry.adapterForViewToken(editorId)?.scalarPositionForDoc(docPos) ?: 0
126
+ }
127
+ private val selectionPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
128
+ style = Paint.Style.FILL
129
+ }
130
+ private val caretPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
131
+ style = Paint.Style.FILL
132
+ }
133
+
134
+ init {
135
+ setWillNotDraw(false)
136
+ isClickable = false
137
+ isFocusable = false
138
+ }
139
+
140
+ fun bind(editorView: RichTextEditorView) {
141
+ this.editorView = editorView
142
+ invalidateGeometry()
143
+ }
144
+
145
+ fun setRemoteSelections(selections: List<RemoteSelectionDecoration>) {
146
+ if (remoteSelections == selections) {
147
+ return
148
+ }
149
+ remoteSelections = selections
150
+ invalidateGeometry()
151
+ refreshGeometry()
152
+ }
153
+
154
+ fun refreshGeometry() {
155
+ ensureGeometry()
156
+ invalidate()
157
+ }
158
+
159
+ fun hasSelectionsOrCachedGeometry(): Boolean =
160
+ remoteSelections.isNotEmpty() || cachedGeometry.isNotEmpty()
161
+
162
+ fun debugSnapshotsForTesting(): List<RemoteSelectionDebugSnapshot> =
163
+ ensureGeometry().map { geometry ->
164
+ RemoteSelectionDebugSnapshot(
165
+ clientId = geometry.clientId,
166
+ caretRect = geometry.caretRect?.let(::RectF)
167
+ )
168
+ }
169
+
170
+ override fun onDraw(canvas: Canvas) {
171
+ super.onDraw(canvas)
172
+ val geometry = ensureGeometry()
173
+ if (geometry.isEmpty()) return
174
+
175
+ for (entry in geometry) {
176
+ entry.selectionPath?.let { path ->
177
+ selectionPaint.color = entry.selectionColor
178
+ canvas.drawPath(path, selectionPaint)
179
+ }
180
+
181
+ entry.caretRect?.let { caretRect ->
182
+ caretPaint.color = entry.caretColor
183
+ val cornerRadius = maxOf(1f, caretRect.width() / 2f)
184
+ canvas.drawRoundRect(
185
+ caretRect.left,
186
+ caretRect.top,
187
+ caretRect.right,
188
+ caretRect.bottom,
189
+ cornerRadius,
190
+ cornerRadius,
191
+ caretPaint
192
+ )
193
+ }
194
+ }
195
+ }
196
+
197
+ private fun ensureGeometry(): List<CachedSelectionGeometry> {
198
+ val context = buildGeometryContext() ?: run {
199
+ cachedSnapshot = null
200
+ cachedGeometry = emptyList()
201
+ return emptyList()
202
+ }
203
+ if (cachedSnapshot == context.snapshot) {
204
+ return cachedGeometry
205
+ }
206
+
207
+ val text = context.snapshot.text
208
+ val editorId = context.snapshot.editorId
209
+ val geometry = remoteSelections.map { selection ->
210
+ val startDoc = minOf(selection.anchor, selection.head)
211
+ val endDoc = maxOf(selection.anchor, selection.head)
212
+ val startScalar = docToScalarResolver(editorId, startDoc)
213
+ val endScalar = docToScalarResolver(editorId, endDoc)
214
+ val startUtf16 = PositionBridge.scalarToUtf16(
215
+ startScalar,
216
+ text
217
+ ).coerceIn(0, text.length)
218
+ val endUtf16 = PositionBridge.scalarToUtf16(endScalar, text).coerceIn(0, text.length)
219
+
220
+ val selectionPath = if (startUtf16 != endUtf16) {
221
+ Path().apply {
222
+ context.layout.getSelectionPath(startUtf16, endUtf16, this)
223
+ offset(context.snapshot.baseX.toFloat(), context.snapshot.baseY.toFloat())
224
+ }
225
+ } else {
226
+ null
227
+ }
228
+
229
+ CachedSelectionGeometry(
230
+ clientId = selection.clientId,
231
+ selectionPath = selectionPath,
232
+ selectionColor = withAlpha(selection.color, 0.18f),
233
+ caretRect = caretRectForOffset(
234
+ endUtf16 = endUtf16,
235
+ textLength = text.length,
236
+ layout = context.layout,
237
+ baseX = context.snapshot.baseX.toFloat(),
238
+ baseY = context.snapshot.baseY.toFloat(),
239
+ caretWidth = context.caretWidth,
240
+ isFocused = selection.isFocused
241
+ ),
242
+ caretColor = selection.color
243
+ )
244
+ }
245
+
246
+ cachedSnapshot = context.snapshot
247
+ cachedGeometry = geometry
248
+ return geometry
249
+ }
250
+
251
+ private fun buildGeometryContext(): GeometryContext? {
252
+ val editorView = editorView ?: return null
253
+ val editorId = resolvedEditorId(editorView)
254
+ if (editorId == 0L || remoteSelections.isEmpty()) return null
255
+
256
+ val editText = editorView.editorEditText
257
+ val layout = editText.layout ?: return null
258
+ val text = editText.text?.toString() ?: return null
259
+ val baseX =
260
+ editorView.editorViewport.left + editorView.editorScrollView.left + editText.left +
261
+ editText.compoundPaddingLeft
262
+ val baseY = editorView.editorViewport.top + editorView.editorScrollView.top + editText.top +
263
+ editText.compoundPaddingTop - editorView.editorScrollView.scrollY
264
+ val caretWidth = maxOf(2f, resources.displayMetrics.density)
265
+
266
+ return GeometryContext(
267
+ snapshot = GeometrySnapshot(
268
+ editorId = editorId,
269
+ text = text,
270
+ layoutWidth = layout.width,
271
+ layoutHeight = layout.height,
272
+ baseX = baseX,
273
+ baseY = baseY,
274
+ width = width,
275
+ height = height,
276
+ selections = remoteSelections
277
+ ),
278
+ layout = layout,
279
+ caretWidth = caretWidth
280
+ )
281
+ }
282
+
283
+ private fun invalidateGeometry() {
284
+ cachedSnapshot = null
285
+ }
286
+
287
+ private fun caretRectForOffset(
288
+ endUtf16: Int,
289
+ textLength: Int,
290
+ layout: android.text.Layout,
291
+ baseX: Float,
292
+ baseY: Float,
293
+ caretWidth: Float,
294
+ isFocused: Boolean
295
+ ): RectF? {
296
+ if (!isFocused) return null
297
+
298
+ val clampedOffset = endUtf16.coerceIn(0, textLength)
299
+ val line = layout.getLineForOffset(clampedOffset)
300
+ val horizontal = layout.getPrimaryHorizontal(clampedOffset)
301
+ val caretLeft = baseX + horizontal
302
+ val caretTop = baseY + layout.editorTextLineTop(line)
303
+ val caretBottom = baseY + layout.editorTextLineBottom(line)
304
+ return RectF(caretLeft, caretTop, caretLeft + caretWidth, caretBottom)
305
+ }
306
+
307
+ private fun withAlpha(color: Int, alphaFraction: Float): Int {
308
+ val alpha = (255f * alphaFraction).toInt().coerceIn(0, 255)
309
+ return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color))
310
+ }
311
+
312
+ private fun resolvedEditorId(editorView: RichTextEditorView): Long =
313
+ editorIdOverrideForTesting ?: editorView.editorId
314
+ }
@@ -0,0 +1,314 @@
1
+ package com.apollohg.editor
2
+
3
+ import android.graphics.Canvas
4
+ import android.graphics.Paint
5
+ import android.graphics.RectF
6
+ import android.text.Annotation
7
+ import android.text.Layout
8
+ import android.text.Spanned
9
+ import android.text.style.LeadingMarginSpan
10
+ import android.text.style.LineBackgroundSpan
11
+ import android.text.style.ReplacementSpan
12
+
13
+ class BlockquoteSpan(
14
+ private val baseIndentPx: Int,
15
+ private val totalIndentPx: Int,
16
+ private val stripeColor: Int,
17
+ private val stripeWidthPx: Int,
18
+ private val gapWidthPx: Int
19
+ ) : LeadingMarginSpan {
20
+
21
+ override fun getLeadingMargin(first: Boolean): Int = totalIndentPx
22
+
23
+ override fun drawLeadingMargin(
24
+ canvas: Canvas,
25
+ paint: Paint,
26
+ x: Int,
27
+ dir: Int,
28
+ top: Int,
29
+ baseline: Int,
30
+ bottom: Int,
31
+ text: CharSequence,
32
+ start: Int,
33
+ end: Int,
34
+ first: Boolean,
35
+ layout: android.text.Layout?
36
+ ) {
37
+ if (!lineContainsQuotedContent(text, start, end)) {
38
+ return
39
+ }
40
+
41
+ val savedColor = paint.color
42
+ val savedStyle = paint.style
43
+
44
+ paint.color = stripeColor
45
+ paint.style = Paint.Style.FILL
46
+
47
+ val stripeStart = x + (dir * baseIndentPx)
48
+ val stripeLeft = if (dir >
49
+ 0
50
+ ) {
51
+ stripeStart.toFloat()
52
+ } else {
53
+ (stripeStart - stripeWidthPx).toFloat()
54
+ }
55
+ val stripeRight = if (dir > 0) stripeLeft + stripeWidthPx else stripeLeft + stripeWidthPx
56
+ val stripeBottom = resolvedStripeBottom(
57
+ text = text,
58
+ start = start,
59
+ end = end,
60
+ baseline = baseline,
61
+ bottom = bottom,
62
+ layout = layout,
63
+ paint = paint
64
+ )
65
+ canvas.drawRect(
66
+ stripeLeft,
67
+ top.toFloat(),
68
+ stripeRight,
69
+ stripeBottom,
70
+ paint
71
+ )
72
+
73
+ paint.color = savedColor
74
+ paint.style = savedStyle
75
+ }
76
+
77
+ private fun lineContainsQuotedContent(text: CharSequence, start: Int, end: Int): Boolean {
78
+ if (start >= end || text !is Spanned) return true
79
+ for (index in start until end.coerceAtMost(text.length)) {
80
+ val ch = text[index]
81
+ if (ch == '\n' || ch == '\r') continue
82
+ val quoted = text.getSpans(index, index + 1, Annotation::class.java).any {
83
+ it.key == RenderBridge.NATIVE_BLOCKQUOTE_ANNOTATION
84
+ }
85
+ if (quoted) {
86
+ return true
87
+ }
88
+ }
89
+ return false
90
+ }
91
+
92
+ internal fun resolvedStripeBottom(
93
+ text: CharSequence,
94
+ start: Int,
95
+ end: Int,
96
+ baseline: Int,
97
+ bottom: Int,
98
+ layout: android.text.Layout?,
99
+ paint: Paint? = null
100
+ ): Float {
101
+ if (layout == null || text.isEmpty()) {
102
+ return bottom.toFloat()
103
+ }
104
+ val lineIndex = safeLineForOffset(layout, start, text.length)
105
+ val nextLine = lineIndex + 1
106
+ if (nextLine >= layout.lineCount) {
107
+ return trimmedTextBottom(baseline, layout, lineIndex, paint)
108
+ }
109
+
110
+ val nextLineStart = layout.getLineStart(nextLine)
111
+ val nextLineEnd = layout.getLineEnd(nextLine)
112
+ return if (lineContainsQuotedContent(text, nextLineStart, nextLineEnd)) {
113
+ bottom.toFloat()
114
+ } else {
115
+ trimmedTextBottom(baseline, layout, lineIndex, paint)
116
+ }
117
+ }
118
+
119
+ private fun trimmedTextBottom(
120
+ baseline: Int,
121
+ layout: Layout,
122
+ lineIndex: Int,
123
+ paint: Paint?
124
+ ): Float {
125
+ val fontDescent = paint?.fontMetrics?.descent
126
+ return if (fontDescent != null) {
127
+ baseline + fontDescent
128
+ } else {
129
+ (baseline + layout.getLineDescent(lineIndex)).toFloat()
130
+ }
131
+ }
132
+
133
+ private fun safeLineForOffset(layout: Layout, offset: Int, textLength: Int): Int {
134
+ if (textLength <= 0) return 0
135
+ val safeStart = offset.coerceIn(0, textLength - 1)
136
+ return layout.getLineForOffset(safeStart)
137
+ }
138
+ }
139
+
140
+ class CodeBlockSpan(
141
+ private val backgroundColor: Int,
142
+ private val cornerRadiusPx: Float,
143
+ private val paddingHorizontalPx: Int,
144
+ private val paddingVerticalPx: Int
145
+ ) : LeadingMarginSpan,
146
+ LineBackgroundSpan {
147
+ internal val documentBox: EditorBoxStyle get() = EditorBoxStyle(
148
+ backgroundColor = backgroundColor,
149
+ padding = EditorEdges(
150
+ paddingVerticalPx.toFloat(),
151
+ paddingHorizontalPx.toFloat(),
152
+ paddingVerticalPx.toFloat(),
153
+ paddingHorizontalPx.toFloat()
154
+ ),
155
+ corners = EditorCorners(cornerRadiusPx, cornerRadiusPx, cornerRadiusPx, cornerRadiusPx)
156
+ )
157
+ override fun getLeadingMargin(first: Boolean): Int = paddingHorizontalPx
158
+
159
+ override fun drawLeadingMargin(
160
+ canvas: Canvas,
161
+ paint: Paint,
162
+ x: Int,
163
+ dir: Int,
164
+ top: Int,
165
+ baseline: Int,
166
+ bottom: Int,
167
+ text: CharSequence,
168
+ start: Int,
169
+ end: Int,
170
+ first: Boolean,
171
+ layout: Layout
172
+ ) = Unit
173
+
174
+ override fun drawBackground(
175
+ canvas: Canvas,
176
+ paint: Paint,
177
+ left: Int,
178
+ right: Int,
179
+ top: Int,
180
+ baseline: Int,
181
+ bottom: Int,
182
+ text: CharSequence,
183
+ start: Int,
184
+ end: Int,
185
+ lineNumber: Int
186
+ ) {
187
+ val spanned = text as? Spanned ?: return
188
+ val spanStart = spanned.getSpanStart(this)
189
+ val spanEnd = spanned.getSpanEnd(this)
190
+ if (spanStart < 0 || start >= spanEnd || end <= spanStart) return
191
+
192
+ val isFirstLine = start <= spanStart
193
+ val isLastLine = end >= spanEnd
194
+ val rect = RectF(
195
+ left.toFloat(),
196
+ if (isFirstLine) top.toFloat() - paddingVerticalPx else top.toFloat(),
197
+ (right - paddingHorizontalPx).toFloat(),
198
+ if (isLastLine) bottom.toFloat() + paddingVerticalPx else bottom.toFloat()
199
+ )
200
+
201
+ val savedColor = paint.color
202
+ val savedStyle = paint.style
203
+ paint.color = backgroundColor
204
+ paint.style = Paint.Style.FILL
205
+
206
+ when {
207
+ isFirstLine && isLastLine -> canvas.drawRoundRect(
208
+ rect,
209
+ cornerRadiusPx,
210
+ cornerRadiusPx,
211
+ paint
212
+ )
213
+
214
+ isFirstLine -> {
215
+ canvas.drawRoundRect(rect, cornerRadiusPx, cornerRadiusPx, paint)
216
+ canvas.drawRect(rect.left, rect.centerY(), rect.right, rect.bottom, paint)
217
+ }
218
+
219
+ isLastLine -> {
220
+ canvas.drawRoundRect(rect, cornerRadiusPx, cornerRadiusPx, paint)
221
+ canvas.drawRect(rect.left, rect.top, rect.right, rect.centerY(), paint)
222
+ }
223
+
224
+ else -> canvas.drawRect(rect, paint)
225
+ }
226
+
227
+ paint.color = savedColor
228
+ paint.style = savedStyle
229
+ }
230
+ }
231
+
232
+ class HorizontalRuleSpan(
233
+ private val lineColor: Int,
234
+ private val lineHeight: Float = LayoutConstants.HORIZONTAL_RULE_HEIGHT,
235
+ private val verticalPadding: Float = LayoutConstants.HORIZONTAL_RULE_VERTICAL_PADDING,
236
+ private val boxInset: EditorEdges = EditorEdges()
237
+ ) : ReplacementSpan(),
238
+ LeadingMarginSpan {
239
+
240
+ override fun getLeadingMargin(first: Boolean): Int = 0
241
+
242
+ override fun getSize(
243
+ paint: Paint,
244
+ text: CharSequence,
245
+ start: Int,
246
+ end: Int,
247
+ fm: Paint.FontMetricsInt?
248
+ ): Int {
249
+ if (fm != null) {
250
+ val totalHeight = kotlin.math.ceil(lineHeight + (verticalPadding * 2)).toInt()
251
+ val halfHeight = totalHeight / 2
252
+ fm.ascent = -halfHeight
253
+ fm.top = fm.ascent
254
+ fm.descent = totalHeight - halfHeight
255
+ fm.bottom = fm.descent
256
+ }
257
+ // Keep the placeholder atom in the text model without reserving
258
+ // visible glyph width, so Android does not paint a tofu/OBJ box.
259
+ return 0
260
+ }
261
+
262
+ override fun drawLeadingMargin(
263
+ canvas: Canvas,
264
+ paint: Paint,
265
+ x: Int,
266
+ dir: Int,
267
+ top: Int,
268
+ baseline: Int,
269
+ bottom: Int,
270
+ text: CharSequence,
271
+ start: Int,
272
+ end: Int,
273
+ first: Boolean,
274
+ layout: android.text.Layout?
275
+ ) {
276
+ val savedColor = paint.color
277
+ val savedStyle = paint.style
278
+
279
+ paint.color = lineColor
280
+ paint.style = Paint.Style.FILL
281
+
282
+ val owned =
283
+ text is Spanned &&
284
+ text.getSpans(start, end, EditorOwnedBlockGeometrySpan::class.java).isNotEmpty()
285
+ val inset = if (owned) EditorEdges() else boxInset
286
+ val lineY = (top + inset.top + bottom - inset.bottom) / 2f
287
+ val lineWidth = (layout?.width?.toFloat() ?: canvas.width.toFloat()) - inset.right
288
+ canvas.drawRect(
289
+ x.toFloat(),
290
+ lineY - lineHeight / 2f,
291
+ lineWidth,
292
+ lineY + lineHeight / 2f,
293
+ paint
294
+ )
295
+
296
+ paint.color = savedColor
297
+ paint.style = savedStyle
298
+ }
299
+
300
+ override fun draw(
301
+ canvas: Canvas,
302
+ text: CharSequence,
303
+ start: Int,
304
+ end: Int,
305
+ x: Float,
306
+ top: Int,
307
+ y: Int,
308
+ bottom: Int,
309
+ paint: Paint
310
+ ) {
311
+ // Intentionally empty: drawLeadingMargin renders the separator line,
312
+ // and ReplacementSpan suppresses drawing the underlying FFFC glyph.
313
+ }
314
+ }