@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,91 @@
1
+ package com.apollohg.editor
2
+
3
+ import android.graphics.Paint
4
+ import android.text.Layout
5
+ import android.text.Spanned
6
+ import android.text.TextPaint
7
+ import android.text.style.MetricAffectingSpan
8
+
9
+ /**
10
+ * Vertical geometry for the text caret, clipped to the rendered glyph height.
11
+ *
12
+ * Android's [android.widget.Editor] draws the native caret from
13
+ * `Layout.editorTextLineTop(line)` to `Layout.editorTextLineBottom(line)`. When a
14
+ * [ParagraphSpacerSpan] inflates a line's descent to create inter-block
15
+ * spacing, `getLineBottom` includes that gap and the caret stretches into it.
16
+ * `getLineBottomWithoutSpacing` cannot help: the inflation lives in the line's
17
+ * DESCENT column, not the line-spacing EXTRA column it subtracts.
18
+ *
19
+ * The baseline is provably independent of descent inflation
20
+ * (`getLineBaseline(line) == getLineTop(line) - ascent`), so anchoring the
21
+ * caret bottom at `baseline + raw font descent` clips it to the glyph height.
22
+ * This mirrors the trim already used for blockquote stripes
23
+ * ([BlockquoteSpan.resolvedStripeBottom]).
24
+ */
25
+ object CaretGeometry {
26
+ data class VerticalBounds(val top: Float, val bottom: Float)
27
+
28
+ /**
29
+ * Whether the manually-drawn caret should be visible. The native caret is
30
+ * suppressed, so this gates our replacement: only when the field is focused,
31
+ * its window is focused, and the selection is a collapsed insertion point
32
+ * (a range selection shows the selection highlight instead).
33
+ */
34
+ fun shouldRender(
35
+ focused: Boolean,
36
+ windowFocused: Boolean,
37
+ selectionStart: Int,
38
+ selectionEnd: Int
39
+ ): Boolean = focused &&
40
+ windowFocused &&
41
+ selectionStart >= 0 &&
42
+ selectionStart == selectionEnd
43
+
44
+ fun verticalBounds(layout: Layout, offset: Int, paint: Paint): VerticalBounds =
45
+ verticalBounds(layout, offset, paint, layout.text)
46
+
47
+ fun verticalBounds(
48
+ layout: Layout,
49
+ offset: Int,
50
+ fallbackPaint: Paint,
51
+ text: CharSequence
52
+ ): VerticalBounds {
53
+ val line = layout.getLineForOffset(offset.coerceIn(0, layout.text.length))
54
+ val top = layout.editorTextLineTop(line).toFloat()
55
+ val resolvedPaint =
56
+ (layout as? EditorDocumentLayout)?.emptyLinePaint(offset) ?: resolvedPaintAtOffset(
57
+ fallbackPaint,
58
+ text,
59
+ offset,
60
+ layout.getLineStart(line)
61
+ )
62
+ val bottom = layout.getLineBaseline(line) + resolvedPaint.fontMetrics.descent
63
+ return VerticalBounds(top, bottom)
64
+ }
65
+
66
+ private fun resolvedPaintAtOffset(
67
+ fallbackPaint: Paint,
68
+ text: CharSequence,
69
+ offset: Int,
70
+ lineStart: Int
71
+ ): TextPaint {
72
+ val resolved = TextPaint(fallbackPaint)
73
+ val spanned = text as? Spanned ?: return resolved
74
+ if (spanned.isEmpty()) {
75
+ spanned.getSpans(0, 0, MetricAffectingSpan::class.java).forEach {
76
+ it.updateMeasureState(resolved)
77
+ }
78
+ return resolved
79
+ }
80
+ val clampedOffset = offset.coerceIn(0, spanned.length)
81
+ val probe = if (clampedOffset > lineStart) {
82
+ clampedOffset - 1
83
+ } else {
84
+ clampedOffset.coerceAtMost(spanned.length - 1)
85
+ }
86
+ spanned.getSpans(probe, probe + 1, MetricAffectingSpan::class.java)
87
+ .filterNot { it is ParagraphSpacerSpan }
88
+ .forEach { it.updateMeasureState(resolved) }
89
+ return resolved
90
+ }
91
+ }
@@ -0,0 +1,141 @@
1
+ package com.apollohg.editor
2
+
3
+ data class CodeHighlightRange(val start: Int, val length: Int, val color: Long, val fontStyle: Int)
4
+
5
+ interface CodeHighlightingProvider {
6
+ val id: String
7
+ val version: Int
8
+ fun highlight(text: String, language: String?, theme: String): List<CodeHighlightRange>
9
+ }
10
+
11
+ object CodeHighlightingRegistry {
12
+ private val providers = mutableMapOf<String, CodeHighlightingProvider>()
13
+
14
+ @Synchronized
15
+ fun register(provider: CodeHighlightingProvider) {
16
+ require(provider.id.isNotEmpty() && provider.version == 1) {
17
+ "Code highlighting provider must have an ID and support version 1"
18
+ }
19
+ providers[provider.id] = provider
20
+ }
21
+
22
+ @Synchronized
23
+ fun provider(id: String): CodeHighlightingProvider = requireNotNull(providers[id]) {
24
+ "Code highlighting provider '$id' is unavailable. Install and import its native package, then rebuild the app."
25
+ }
26
+
27
+ internal fun validRanges(text: String, ranges: List<CodeHighlightRange>): Boolean {
28
+ fun isBoundary(offset: Int): Boolean = offset == 0 || offset == text.length ||
29
+ !Character.isHighSurrogate(text[offset - 1]) || !Character.isLowSurrogate(text[offset])
30
+ var end = 0
31
+ for (range in ranges) {
32
+ if (range.start < end || range.length <= 0 || range.start > text.length ||
33
+ range.length > text.length - range.start || range.color !in 0L..0xffffffffL ||
34
+ range.fontStyle !in 0..7 || !isBoundary(range.start) ||
35
+ !isBoundary(range.start + range.length)
36
+ ) {
37
+ return false
38
+ }
39
+ end = range.start + range.length
40
+ }
41
+ return true
42
+ }
43
+ }
44
+
45
+ internal data class CodeHighlightBlock(val start: Int, val text: String, val language: String?)
46
+ internal data class HighlightedCodeBlock(
47
+ val block: CodeHighlightBlock,
48
+ val ranges: List<CodeHighlightRange>
49
+ )
50
+
51
+ internal class CodeHighlightingSession {
52
+ private data class Request(
53
+ val generation: Long,
54
+ val provider: CodeHighlightingProvider,
55
+ val theme: String,
56
+ val blocks: List<CodeHighlightBlock>,
57
+ val completion: (Result<List<HighlightedCodeBlock>>) -> Unit
58
+ )
59
+
60
+ companion object {
61
+ private val executor = java.util.concurrent.Executors.newSingleThreadExecutor { task ->
62
+ Thread(task, "editor.code-highlighting").apply { isDaemon = true }
63
+ }
64
+ }
65
+
66
+ private val lock = Any()
67
+ private val main = android.os.Handler(android.os.Looper.getMainLooper())
68
+ private var generation = 0L
69
+ private var pending: Request? = null
70
+ private var running = false
71
+
72
+ fun cancel() {
73
+ check(android.os.Looper.myLooper() == android.os.Looper.getMainLooper()) {
74
+ "Highlighting sessions must be updated on the main thread"
75
+ }
76
+ synchronized(lock) {
77
+ generation++
78
+ pending = null
79
+ }
80
+ }
81
+
82
+ fun update(
83
+ provider: String,
84
+ theme: String,
85
+ blocks: List<CodeHighlightBlock>,
86
+ completion: (Result<List<HighlightedCodeBlock>>) -> Unit
87
+ ) {
88
+ cancel()
89
+ val resolved = CodeHighlightingRegistry.provider(provider)
90
+ val schedule = synchronized(lock) {
91
+ pending = Request(generation, resolved, theme, blocks.toList(), completion)
92
+ (!running).also { running = true }
93
+ }
94
+ if (schedule) executor.execute { drain() }
95
+ }
96
+
97
+ private fun current(value: Long) = synchronized(lock) { generation == value }
98
+
99
+ private fun takeRequest(): Request? = synchronized(lock) {
100
+ pending.also {
101
+ pending = null
102
+ if (it == null) running = false
103
+ }
104
+ }
105
+
106
+ private fun scheduleNext() {
107
+ val schedule = synchronized(lock) {
108
+ (pending != null).also { running = it }
109
+ }
110
+ if (schedule) executor.execute { drain() }
111
+ }
112
+
113
+ private fun drain() {
114
+ val request = takeRequest() ?: return
115
+ try {
116
+ val result = runCatching {
117
+ val output = mutableListOf<HighlightedCodeBlock>()
118
+ for (block in request.blocks) {
119
+ if (!current(request.generation)) break
120
+ val ranges = request.provider.highlight(
121
+ block.text,
122
+ block.language,
123
+ request.theme
124
+ ).toList()
125
+ require(CodeHighlightingRegistry.validRanges(block.text, ranges)) {
126
+ "Code highlighting provider returned invalid UTF-16 ranges"
127
+ }
128
+ output.add(HighlightedCodeBlock(block, ranges))
129
+ }
130
+ output.toList()
131
+ }
132
+ if (current(request.generation)) {
133
+ main.post {
134
+ if (current(request.generation)) request.completion(result)
135
+ }
136
+ }
137
+ } finally {
138
+ scheduleNext()
139
+ }
140
+ }
141
+ }
@@ -0,0 +1,250 @@
1
+ package com.apollohg.editor
2
+
3
+ import android.app.ActivityManager
4
+ import android.content.Context
5
+ import android.graphics.Bitmap
6
+ import java.io.Closeable
7
+ import java.util.concurrent.atomic.AtomicBoolean
8
+ import java.util.concurrent.atomic.AtomicLong
9
+
10
+ internal enum class DecodedBitmapPriority { VISIBLE, PREFETCH }
11
+
12
+ internal class DecodedBitmapBudget(private val processLimitBytes: Long) {
13
+ internal class Allocation(
14
+ var bytes: Long,
15
+ var bitmap: Bitmap? = null,
16
+ var references: Int = 1,
17
+ val ownerReferences: MutableMap<Long, Int> = mutableMapOf(),
18
+ val ownerPriorityReferences: MutableMap<Pair<Long, DecodedBitmapPriority>, Int> =
19
+ mutableMapOf()
20
+ )
21
+
22
+ private val lock = Any()
23
+ private var retainedProcessBytes = 0L
24
+ private val retainedOwnerBytes = mutableMapOf<Long, Long>()
25
+ private val ownerPressureHandlers = mutableMapOf<Long, () -> Unit>()
26
+
27
+ @Volatile private var pressureHandler: (() -> Unit)? = null
28
+
29
+ fun reserve(bytes: Long, priority: DecodedBitmapPriority): DecodedBitmapReservation? {
30
+ if (bytes <= 0L || bytes > processLimitBytes) return null
31
+ fun attempt(): Allocation? = synchronized(lock) {
32
+ val next = checkedAdd(retainedProcessBytes, bytes) ?: return@synchronized null
33
+ if (next > processLimitBytes) return@synchronized null
34
+ retainedProcessBytes = next
35
+ Allocation(bytes)
36
+ }
37
+ var allocation = attempt()
38
+ if (allocation == null && priority == DecodedBitmapPriority.VISIBLE) {
39
+ pressureHandler?.invoke()
40
+ allocation = attempt()
41
+ if (allocation == null) {
42
+ synchronized(lock) { ownerPressureHandlers.values.toList() }.forEach { it() }
43
+ pressureHandler?.invoke()
44
+ allocation = attempt()
45
+ }
46
+ }
47
+ allocation ?: return null
48
+ return DecodedBitmapReservation(this, allocation)
49
+ }
50
+
51
+ fun setPressureHandler(handler: (() -> Unit)?) {
52
+ pressureHandler = handler
53
+ }
54
+
55
+ fun setOwnerPressureHandler(ownerId: Long, handler: (() -> Unit)?) = synchronized(lock) {
56
+ if (handler == null) {
57
+ ownerPressureHandlers.remove(ownerId)
58
+ } else {
59
+ ownerPressureHandlers[ownerId] = handler
60
+ }
61
+ }
62
+
63
+ private fun reconcile(allocation: Allocation, actualBytes: Long): Boolean = synchronized(lock) {
64
+ if (actualBytes <= 0L || allocation.references <= 0) return@synchronized false
65
+ val withoutAllocation = retainedProcessBytes - allocation.bytes
66
+ val next = checkedAdd(withoutAllocation, actualBytes) ?: return@synchronized false
67
+ if (next > processLimitBytes) return@synchronized false
68
+ retainedProcessBytes = next
69
+ allocation.bytes = actualBytes
70
+ true
71
+ }
72
+
73
+ private fun fork(
74
+ allocation: Allocation,
75
+ ownerId: Long,
76
+ ownerLimitBytes: Long,
77
+ priority: DecodedBitmapPriority
78
+ ): DecodedBitmapLease? {
79
+ if (ownerLimitBytes <= 0L || allocation.bytes > ownerLimitBytes) return null
80
+ fun attempt(): DecodedBitmapLease? = synchronized(lock) {
81
+ if (allocation.references <= 0 || allocation.bitmap == null) {
82
+ return@synchronized null
83
+ }
84
+ val ownerReferences = allocation.ownerReferences[ownerId] ?: 0
85
+ if (ownerReferences == 0) {
86
+ val retained = retainedOwnerBytes[ownerId] ?: 0L
87
+ val next = checkedAdd(retained, allocation.bytes) ?: return@synchronized null
88
+ if (next > ownerLimitBytes) return@synchronized null
89
+ retainedOwnerBytes[ownerId] = next
90
+ }
91
+ val priorityKey = ownerId to priority
92
+ val priorityReferences = allocation.ownerPriorityReferences[priorityKey] ?: 0
93
+ if (
94
+ allocation.references == Int.MAX_VALUE ||
95
+ ownerReferences == Int.MAX_VALUE ||
96
+ priorityReferences == Int.MAX_VALUE
97
+ ) {
98
+ return@synchronized null
99
+ }
100
+ allocation.references += 1
101
+ allocation.ownerReferences[ownerId] = ownerReferences + 1
102
+ allocation.ownerPriorityReferences[priorityKey] = priorityReferences + 1
103
+ DecodedBitmapLease(this, allocation, ownerId, priority)
104
+ }
105
+ var lease = attempt()
106
+ if (lease == null && priority == DecodedBitmapPriority.VISIBLE) {
107
+ synchronized(lock) { ownerPressureHandlers[ownerId] }?.invoke()
108
+ lease = attempt()
109
+ }
110
+ return lease
111
+ }
112
+
113
+ private fun forkUnowned(allocation: Allocation): DecodedBitmapLease? = synchronized(lock) {
114
+ if (allocation.references <= 0 || allocation.bitmap == null ||
115
+ allocation.references == Int.MAX_VALUE
116
+ ) {
117
+ return@synchronized null
118
+ }
119
+ allocation.references += 1
120
+ DecodedBitmapLease(this, allocation, null, null)
121
+ }
122
+
123
+ private fun release(allocation: Allocation, ownerId: Long?, priority: DecodedBitmapPriority?) =
124
+ synchronized(lock) {
125
+ if (allocation.references <= 0) return@synchronized
126
+ if (ownerId != null) {
127
+ val references = allocation.ownerReferences[ownerId] ?: return@synchronized
128
+ val priorityKey = ownerId to checkNotNull(priority)
129
+ val priorityReferences = allocation.ownerPriorityReferences[priorityKey]
130
+ ?: return@synchronized
131
+ if (priorityReferences == 1) {
132
+ allocation.ownerPriorityReferences.remove(priorityKey)
133
+ } else {
134
+ allocation.ownerPriorityReferences[priorityKey] = priorityReferences - 1
135
+ }
136
+ if (references == 1) {
137
+ allocation.ownerReferences.remove(ownerId)
138
+ val remaining = (retainedOwnerBytes[ownerId] ?: 0L) - allocation.bytes
139
+ if (remaining <= 0L) {
140
+ retainedOwnerBytes.remove(ownerId)
141
+ } else {
142
+ retainedOwnerBytes[ownerId] = remaining
143
+ }
144
+ } else {
145
+ allocation.ownerReferences[ownerId] = references - 1
146
+ }
147
+ }
148
+ allocation.references -= 1
149
+ if (allocation.references == 0) {
150
+ retainedProcessBytes = (retainedProcessBytes - allocation.bytes).coerceAtLeast(0L)
151
+ allocation.bitmap = null
152
+ allocation.ownerReferences.clear()
153
+ allocation.ownerPriorityReferences.clear()
154
+ }
155
+ }
156
+
157
+ internal fun retainedProcessBytesForTesting(): Long = synchronized(lock) {
158
+ retainedProcessBytes
159
+ }
160
+
161
+ internal fun retainedOwnerBytesForTesting(ownerId: Long): Long =
162
+ synchronized(lock) { retainedOwnerBytes[ownerId] ?: 0L }
163
+
164
+ internal companion object {
165
+ private const val MIB = 1024L * 1024L
166
+ private val ownerIds = AtomicLong()
167
+ private val sharedLock = Any()
168
+
169
+ @Volatile private var sharedBudget: DecodedBitmapBudget? = null
170
+
171
+ fun processLimitBytes(memoryClassMib: Int): Long =
172
+ (memoryClassMib.coerceAtLeast(0).toLong() * MIB / 8L)
173
+ .coerceIn(16L * MIB, 128L * MIB)
174
+
175
+ fun shared(context: Context? = null): DecodedBitmapBudget {
176
+ sharedBudget?.let { return it }
177
+ return synchronized(sharedLock) {
178
+ sharedBudget ?: DecodedBitmapBudget(
179
+ processLimitBytes(
180
+ context?.applicationContext
181
+ ?.getSystemService(Context.ACTIVITY_SERVICE)
182
+ ?.let { it as? ActivityManager }
183
+ ?.memoryClass
184
+ ?: (Runtime.getRuntime().maxMemory() / MIB)
185
+ .coerceAtMost(Int.MAX_VALUE.toLong())
186
+ .toInt()
187
+ )
188
+ ).also { sharedBudget = it }
189
+ }
190
+ }
191
+
192
+ fun nextOwnerId(): Long = ownerIds.incrementAndGet()
193
+
194
+ private fun checkedAdd(left: Long, right: Long): Long? =
195
+ if (left < 0L || right < 0L || left > Long.MAX_VALUE - right) null else left + right
196
+ }
197
+
198
+ internal class DecodedBitmapReservation internal constructor(
199
+ private val budget: DecodedBitmapBudget,
200
+ private val allocation: Allocation
201
+ ) : Closeable {
202
+ private val finished = AtomicBoolean(false)
203
+
204
+ fun commit(bitmap: Bitmap, actualBytes: Long): DecodedBitmapLease? {
205
+ if (!finished.compareAndSet(false, true)) return null
206
+ if (!budget.reconcile(allocation, actualBytes)) {
207
+ budget.release(allocation, null, null)
208
+ return null
209
+ }
210
+ allocation.bitmap = bitmap
211
+ return DecodedBitmapLease(budget, allocation, null, null)
212
+ }
213
+
214
+ override fun close() {
215
+ if (finished.compareAndSet(false, true)) budget.release(allocation, null, null)
216
+ }
217
+ }
218
+
219
+ internal class DecodedBitmapLease internal constructor(
220
+ private val budget: DecodedBitmapBudget,
221
+ private val allocation: Allocation,
222
+ private val ownerId: Long?,
223
+ private val priority: DecodedBitmapPriority?
224
+ ) : Closeable {
225
+ private val closed = AtomicBoolean(false)
226
+ val bitmap: Bitmap get() = checkNotNull(allocation.bitmap)
227
+ val byteCount: Long get() = allocation.bytes
228
+
229
+ fun fork(
230
+ ownerId: Long,
231
+ ownerLimitBytes: Long,
232
+ priority: DecodedBitmapPriority
233
+ ): DecodedBitmapLease? {
234
+ if (closed.get()) return null
235
+ return budget.fork(allocation, ownerId, ownerLimitBytes, priority)
236
+ }
237
+
238
+ internal fun forkUnowned(): DecodedBitmapLease? {
239
+ if (closed.get()) return null
240
+ return budget.forkUnowned(allocation)
241
+ }
242
+
243
+ override fun close() {
244
+ if (closed.compareAndSet(false, true)) budget.release(allocation, ownerId, priority)
245
+ }
246
+ }
247
+ }
248
+
249
+ internal typealias DecodedBitmapReservation = DecodedBitmapBudget.DecodedBitmapReservation
250
+ internal typealias DecodedBitmapLease = DecodedBitmapBudget.DecodedBitmapLease
@@ -0,0 +1,133 @@
1
+ package com.apollohg.editor
2
+
3
+ import org.json.JSONObject
4
+
5
+ data class NativeMentionSuggestion(
6
+ val key: String,
7
+ val title: String,
8
+ val subtitle: String?,
9
+ val label: String,
10
+ val attrs: JSONObject
11
+ ) {
12
+ companion object {
13
+ fun fromJson(json: JSONObject?): NativeMentionSuggestion? {
14
+ json ?: return null
15
+ val key = json.optString("key", "")
16
+ val title = json.optString("title", "")
17
+ val label = json.optString("label", "")
18
+ if (key.isBlank() || title.isBlank() || label.isBlank()) return null
19
+ return NativeMentionSuggestion(
20
+ key = key,
21
+ title = title,
22
+ subtitle = json.takeUnless { it.isNull("subtitle") }?.optString("subtitle"),
23
+ label = label,
24
+ attrs = json.optJSONObject("attrs") ?: JSONObject()
25
+ )
26
+ }
27
+ }
28
+ }
29
+
30
+ data class NativeMentionsAddonConfig(
31
+ val trigger: String,
32
+ val suggestions: List<NativeMentionSuggestion>,
33
+ val theme: EditorMentionTheme?,
34
+ val resolveSelectionAttrs: Boolean,
35
+ val resolveTheme: Boolean
36
+ ) {
37
+ companion object {
38
+ fun fromJson(json: JSONObject?): NativeMentionsAddonConfig? {
39
+ json ?: return null
40
+ val trigger = json.optString("trigger", "@").ifBlank { "@" }
41
+ val rawSuggestions = json.optJSONArray("suggestions")
42
+ val suggestions = mutableListOf<NativeMentionSuggestion>()
43
+ if (rawSuggestions != null) {
44
+ for (index in 0 until rawSuggestions.length()) {
45
+ val suggestion = NativeMentionSuggestion.fromJson(
46
+ rawSuggestions.optJSONObject(index)
47
+ )
48
+ if (suggestion != null) {
49
+ suggestions.add(suggestion)
50
+ }
51
+ }
52
+ }
53
+ return NativeMentionsAddonConfig(
54
+ trigger = trigger,
55
+ suggestions = suggestions,
56
+ theme = EditorMentionTheme.fromJson(json.optJSONObject("theme")),
57
+ resolveSelectionAttrs = json.optBoolean("resolveSelectionAttrs", false),
58
+ resolveTheme = json.optBoolean("resolveTheme", false)
59
+ )
60
+ }
61
+ }
62
+ }
63
+
64
+ data class NativeEditorAddons(
65
+ val mentions: NativeMentionsAddonConfig?,
66
+ val codeHighlighting: NativeCodeHighlightingConfig? = null
67
+ ) {
68
+ companion object {
69
+ fun fromJson(json: String?): NativeEditorAddons {
70
+ if (json.isNullOrBlank()) return NativeEditorAddons(null)
71
+ val root = try {
72
+ JSONObject(json)
73
+ } catch (_: Exception) {
74
+ return NativeEditorAddons(null)
75
+ }
76
+ return NativeEditorAddons(
77
+ mentions = NativeMentionsAddonConfig.fromJson(root.optJSONObject("mentions")),
78
+ codeHighlighting = NativeCodeHighlightingConfig.fromJson(
79
+ root.optJSONObject("codeHighlighting")
80
+ )
81
+ )
82
+ }
83
+ }
84
+ }
85
+
86
+ data class MentionQueryState(val query: String, val trigger: String, val anchor: Int, val head: Int)
87
+
88
+ internal fun isMentionIdentifierCodePoint(codePoint: Int): Boolean =
89
+ Character.isLetterOrDigit(codePoint) || codePoint == '_'.code || codePoint == '-'.code
90
+
91
+ internal fun resolveMentionQueryState(
92
+ text: String,
93
+ cursorScalar: Int,
94
+ trigger: String,
95
+ isCaretInsideMention: Boolean
96
+ ): MentionQueryState? {
97
+ if (isCaretInsideMention) return null
98
+
99
+ val scalars = text.codePoints().toArray()
100
+ if (cursorScalar > scalars.size) return null
101
+ val triggerCodePoint = trigger.codePointAt(0)
102
+
103
+ var start = cursorScalar
104
+ while (start > 0) {
105
+ val previous = scalars[start - 1]
106
+ if (Character.isWhitespace(previous) ||
107
+ previous == '\n'.code ||
108
+ previous == 0xFFFC ||
109
+ (!isMentionIdentifierCodePoint(previous) && previous != triggerCodePoint)
110
+ ) {
111
+ break
112
+ }
113
+ start -= 1
114
+ }
115
+
116
+ if (start >= scalars.size || scalars[start] != triggerCodePoint) return null
117
+ if (start > 0) {
118
+ val previous = scalars[start - 1]
119
+ if (isMentionIdentifierCodePoint(previous)) {
120
+ return null
121
+ }
122
+ }
123
+
124
+ val query = String(scalars, start + 1, cursorScalar - (start + 1))
125
+ if (query.any { it.isWhitespace() }) return null
126
+
127
+ return MentionQueryState(
128
+ query = query,
129
+ trigger = trigger,
130
+ anchor = start,
131
+ head = cursorScalar
132
+ )
133
+ }
@@ -0,0 +1,51 @@
1
+ package com.apollohg.editor
2
+
3
+ import android.text.Spanned
4
+
5
+ internal fun Spanned.resolvedBlockSpacing(): Map<EditorBlockBoxSpan, EditorBoxStyle> {
6
+ data class Box(val span: EditorBlockBoxSpan, val start: Int, val end: Int)
7
+ val spans = getSpans(0, length, EditorBlockBoxSpan::class.java)
8
+ .map { Box(it, getSpanStart(it), getSpanEnd(it)) }
9
+ .sortedWith(compareBy({ it.start }, { it.span.depth }, { -it.end }))
10
+ val styles = spans.associate { it.span to it.span.box }.toMutableMap()
11
+ val stack = mutableListOf<Box>()
12
+ val children = mutableMapOf<Box?, MutableList<Box>>()
13
+ for (span in spans) {
14
+ while (stack.isNotEmpty() &&
15
+ (stack.last().span.depth >= span.span.depth || stack.last().end < span.end)
16
+ ) {
17
+ stack.removeAt(stack.lastIndex)
18
+ }
19
+ children.getOrPut(stack.lastOrNull()) { mutableListOf() }.add(span)
20
+ stack.add(span)
21
+ }
22
+ for ((parent, siblings) in children) {
23
+ val last = siblings.last()
24
+ if (parent?.span?.nodeType == "blockquote" && last.span.nodeType == "paragraph" &&
25
+ last.end == parent.end
26
+ ) {
27
+ styles[last.span] = last.span.box.copy(margin = last.span.box.margin.copy(bottom = 0f))
28
+ }
29
+ for ((previous, current) in siblings.zipWithNext()) {
30
+ val start = previous.end
31
+ val end = current.start
32
+ if (start > end ||
33
+ (start until end).any { this[it] != '\n' && this[it] != '\u200B' }
34
+ ) {
35
+ continue
36
+ }
37
+ val bottom = previous.span.marginForCollapsing.bottom
38
+ val top = current.span.marginForCollapsing.top
39
+ val collapsed = maxOf(0f, bottom, top) + minOf(0f, bottom, top)
40
+ val style = styles.getValue(current.span)
41
+ styles[current.span] =
42
+ style.copy(
43
+ margin = style.margin.copy(
44
+ top =
45
+ style.margin.top + collapsed - bottom - top
46
+ )
47
+ )
48
+ }
49
+ }
50
+ return styles
51
+ }
@@ -0,0 +1,16 @@
1
+ package com.apollohg.editor
2
+
3
+ import android.graphics.Canvas
4
+ import android.graphics.ColorFilter
5
+ import android.graphics.PixelFormat
6
+ import android.graphics.RectF
7
+ import android.graphics.drawable.Drawable
8
+
9
+ internal class EditorBoxDrawable(private val box: EditorBoxStyle) : Drawable() {
10
+ override fun draw(canvas: Canvas) = EditorBoxDrawing.draw(canvas, RectF(bounds), box)
11
+ override fun setAlpha(alpha: Int) = Unit
12
+ override fun setColorFilter(colorFilter: ColorFilter?) = Unit
13
+
14
+ @Deprecated("Drawable opacity is no longer used")
15
+ override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
16
+ }