@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,288 @@
1
+ import CryptoKit
2
+ import ImageIO
3
+ import UIKit
4
+
5
+ extension RenderBridge {
6
+ /// Build NSAttributedString attributes for a set of render marks.
7
+ ///
8
+ /// Supported marks:
9
+ /// - `bold` -> adds `.traitBold` to the font descriptor
10
+ /// - `italic` -> adds `.traitItalic` to the font descriptor
11
+ /// - `underline` -> sets `.underlineStyle = .single`
12
+ /// - `strike` / `strikethrough` -> sets `.strikethroughStyle = .single`
13
+ /// - `code` -> uses a monospaced font variant
14
+ ///
15
+ /// Multiple marks are combined: "bold italic" produces a bold-italic font.
16
+ static func attributesForMarks(
17
+ _ marks: [Any],
18
+ baseFont: UIFont,
19
+ textColor: UIColor,
20
+ theme: EditorTheme? = nil
21
+ ) -> [NSAttributedString.Key: Any] {
22
+ if let sheet = theme?.styleSheet {
23
+ return sheet.inlineAttributes(marks, base: defaultAttributes(baseFont: baseFont, textColor: textColor))
24
+ }
25
+ var attrs = defaultAttributes(baseFont: baseFont, textColor: textColor)
26
+
27
+ if marks.isEmpty {
28
+ return attrs
29
+ }
30
+
31
+ var traits: UIFontDescriptor.SymbolicTraits = []
32
+ var useMonospace = false
33
+ var linkTheme: EditorLinkTheme?
34
+ var shouldUnderline = false
35
+ for mark in marks {
36
+ let markObject = mark as? [String: Any]
37
+ let markType: String
38
+ if let markName = mark as? String {
39
+ markType = markName
40
+ } else if let resolvedType = markObject?["type"] as? String {
41
+ markType = resolvedType
42
+ } else {
43
+ continue
44
+ }
45
+
46
+ switch markType {
47
+ case "bold", "strong":
48
+ traits.insert(.traitBold)
49
+ case "italic", "em":
50
+ traits.insert(.traitItalic)
51
+ case "underline":
52
+ shouldUnderline = true
53
+ case "strike", "strikethrough":
54
+ attrs[.strikethroughStyle] = NSUnderlineStyle.single.rawValue
55
+ case "code":
56
+ useMonospace = true
57
+ case "link":
58
+ linkTheme = theme?.links
59
+ if theme?.links?.underline ?? true {
60
+ shouldUnderline = true
61
+ }
62
+ attrs[.foregroundColor] = theme?.links?.color ?? UIColor.systemBlue
63
+ if let backgroundColor = theme?.links?.backgroundColor {
64
+ attrs[.backgroundColor] = backgroundColor
65
+ }
66
+ if let href = markObject?["href"] as? String, !href.isEmpty {
67
+ attrs[RenderBridgeAttributes.linkHref] = href
68
+ }
69
+ default:
70
+ break
71
+ }
72
+ }
73
+
74
+ var resolvedFont = linkTheme?.resolvedFont(fallback: baseFont) ?? baseFont
75
+
76
+ resolvedFont = ViewerFontEnvironment.shared.resolveFont(
77
+ family: useMonospace ? "monospace" : nil,
78
+ size: resolvedFont.pointSize,
79
+ fallback: resolvedFont,
80
+ additionalTraits: traits,
81
+ semanticGeneration: "legacy-editor-theme"
82
+ )
83
+
84
+ if shouldUnderline {
85
+ attrs[.underlineStyle] = NSUnderlineStyle.single.rawValue
86
+ }
87
+ attrs[.font] = resolvedFont
88
+ return attrs
89
+ }
90
+
91
+ /// Create an attributed string for a void inline element (e.g. hardBreak).
92
+ ///
93
+ /// A hardBreak is rendered as a newline character with custom attributes
94
+ /// so the position bridge knows it represents a single doc position.
95
+ static func attributedStringForVoidInline(
96
+ nodeType: String,
97
+ docPos: UInt32,
98
+ attrs _: [String: Any],
99
+ baseFont: UIFont,
100
+ textColor: UIColor,
101
+ blockStack: [BlockContext],
102
+ topLevelChildIndex _: Int?,
103
+ theme: EditorTheme?
104
+ ) -> NSAttributedString {
105
+ let blockFont = resolvedFont(for: blockStack, baseFont: baseFont, theme: theme)
106
+ let blockColor = resolvedTextColor(for: blockStack, textColor: textColor, theme: theme)
107
+ var attrs = defaultAttributes(baseFont: blockFont, textColor: blockColor)
108
+ attrs[RenderBridgeAttributes.voidNodeType] = nodeType
109
+ attrs[RenderBridgeAttributes.docPos] = docPos
110
+ let styledAttrs = applyBlockStyle(
111
+ to: attrs,
112
+ blockStack: blockStack,
113
+ theme: theme,
114
+ blockBaseFont: blockFont
115
+ )
116
+
117
+ switch nodeType {
118
+ case "hardBreak", "hard_break":
119
+ var hardBreakAttrs = styledAttrs
120
+ if let paragraphStyle = (hardBreakAttrs[.paragraphStyle] as? NSParagraphStyle)?.mutableCopy()
121
+ as? NSMutableParagraphStyle {
122
+ paragraphStyle.paragraphSpacing = 0
123
+ hardBreakAttrs[.paragraphStyle] = paragraphStyle
124
+ }
125
+ return NSAttributedString(string: "\n", attributes: hardBreakAttrs)
126
+ default:
127
+ return NSAttributedString(
128
+ string: LayoutConstants.objectReplacementCharacter,
129
+ attributes: styledAttrs
130
+ )
131
+ }
132
+ }
133
+
134
+ /// Create an attributed string for a void block element (e.g. horizontalRule).
135
+ ///
136
+ /// Horizontal rules are rendered as U+FFFC (object replacement character)
137
+ /// with an NSTextAttachment that draws a separator line.
138
+ static func attributedStringForVoidBlock(
139
+ nodeType: String,
140
+ docPos: UInt32,
141
+ elementAttrs: [String: Any],
142
+ baseFont: UIFont,
143
+ textColor: UIColor,
144
+ topLevelChildIndex: Int?,
145
+ theme: EditorTheme?,
146
+ atomKey: String,
147
+ atomConfiguration: AtomRenderConfiguration?
148
+ ) -> NSAttributedString {
149
+ var attrs = defaultAttributes(baseFont: baseFont, textColor: textColor)
150
+ attrs[RenderBridgeAttributes.voidNodeType] = nodeType
151
+ attrs[RenderBridgeAttributes.docPos] = docPos
152
+ if let topLevelChildIndex {
153
+ attrs[RenderBridgeAttributes.topLevelChildIndex] = NSNumber(value: topLevelChildIndex)
154
+ }
155
+
156
+ if atomConfiguration?.registeredNodeTypes.contains(nodeType) == true {
157
+ let attachment = AtomBlockAttachment(
158
+ atomKey: atomKey,
159
+ nodeType: nodeType,
160
+ docPos: docPos,
161
+ reservedHeight: atomConfiguration?.reservedHeight(
162
+ atomKey: atomKey,
163
+ nodeType: nodeType
164
+ ) ?? 0
165
+ )
166
+ let attrStr = NSMutableAttributedString(attachment: attachment)
167
+ attrStr.addAttributes(attrs, range: NSRange(location: 0, length: attrStr.length))
168
+ return attrStr
169
+ }
170
+
171
+ switch nodeType {
172
+ case "horizontalRule", "horizontal_rule":
173
+ let attachment = HorizontalRuleAttachment()
174
+ attachment.styleBox = theme?.styleSheet?.box("horizontalRule")
175
+ attachment.lineColor = theme?.horizontalRule?.color ?? textColor.withAlphaComponent(0.3)
176
+ attachment.lineHeight = theme?.horizontalRule?.thickness ?? LayoutConstants.horizontalRuleHeight
177
+ attachment.verticalPadding = resolvedHorizontalRuleVerticalMargin(theme: theme)
178
+ let attrStr = NSMutableAttributedString(
179
+ attachment: attachment
180
+ )
181
+ let range = NSRange(location: 0, length: attrStr.length)
182
+ attrStr.addAttributes(attrs, range: range)
183
+ return attrStr
184
+ case "image":
185
+ guard let source = (elementAttrs["src"] as? String)?.trimmingCharacters(in: .whitespacesAndNewlines),
186
+ !source.isEmpty
187
+ else {
188
+ return NSAttributedString(
189
+ string: LayoutConstants.objectReplacementCharacter,
190
+ attributes: attrs
191
+ )
192
+ }
193
+ let attachment = BlockImageAttachment(
194
+ source: source,
195
+ placeholderTint: textColor,
196
+ preferredWidth: jsonCGFloat(elementAttrs["width"]),
197
+ preferredHeight: jsonCGFloat(elementAttrs["height"])
198
+ )
199
+ attachment.styleBox = theme?.styleSheet?.box("image")
200
+ let attrStr = NSMutableAttributedString(attachment: attachment)
201
+ let range = NSRange(location: 0, length: attrStr.length)
202
+ attrStr.addAttributes(attrs, range: range)
203
+ return attrStr
204
+ default:
205
+ return NSAttributedString(
206
+ string: LayoutConstants.objectReplacementCharacter,
207
+ attributes: attrs
208
+ )
209
+ }
210
+ }
211
+
212
+ /// Create an attributed string for an opaque inline atom (unknown inline void).
213
+ static func attributedStringForOpaqueInlineAtom(
214
+ nodeType: String,
215
+ label: String,
216
+ docPos: UInt32,
217
+ baseFont: UIFont,
218
+ textColor: UIColor,
219
+ blockStack: [BlockContext],
220
+ topLevelChildIndex _: Int?,
221
+ theme: EditorTheme?,
222
+ mentionTheme: EditorMentionTheme?
223
+ ) -> NSAttributedString {
224
+ let blockFont = resolvedFont(for: blockStack, baseFont: baseFont, theme: theme)
225
+ let blockColor = resolvedTextColor(for: blockStack, textColor: textColor, theme: theme)
226
+ var attrs = defaultAttributes(baseFont: blockFont, textColor: blockColor)
227
+ attrs[RenderBridgeAttributes.voidNodeType] = nodeType
228
+ attrs[RenderBridgeAttributes.docPos] = docPos
229
+ if nodeType == "mention" {
230
+ let resolvedMentionTheme = theme?.mentions?.merged(with: mentionTheme) ?? mentionTheme
231
+ let node = resolvedMentionTheme?.node
232
+ attrs[.foregroundColor] = node?.textColor ?? blockColor
233
+ attrs[.backgroundColor] =
234
+ node?.backgroundColor ?? UIColor.systemBlue.withAlphaComponent(0.12)
235
+ if let mentionFont = mentionFont(from: blockFont, theme: node) {
236
+ attrs[.font] = mentionFont
237
+ }
238
+ if let values = node?.style, !values.isEmpty {
239
+ EditorStyleSheet.applyText(values, to: &attrs)
240
+ var boxValues = values
241
+ boxValues["backgroundColor"] = values["backgroundColor"] ?? "#007aff1f"
242
+ attrs.removeValue(forKey: .backgroundColor)
243
+ let chip = EditorMentionRenderedBox(box: EditorStyleBox(boxValues), label: NSAttributedString(string: label, attributes: attrs))
244
+ attrs[editorMentionBoxAttribute] = chip
245
+ attrs[editorInlineLineHeightAttribute] = chip.size.height
246
+ }
247
+ } else {
248
+ attrs[.backgroundColor] = UIColor.systemGray5
249
+ }
250
+ let styledAttrs = applyBlockStyle(
251
+ to: attrs,
252
+ blockStack: blockStack,
253
+ theme: theme,
254
+ blockBaseFont: blockFont
255
+ )
256
+
257
+ let visibleText = nodeType == "mention" ? label : "[\(label)]"
258
+ return NSAttributedString(string: visibleText, attributes: styledAttrs)
259
+ }
260
+
261
+ /// Create an attributed string for an opaque block atom (unknown block void).
262
+ static func attributedStringForOpaqueBlockAtom(
263
+ nodeType: String,
264
+ label: String,
265
+ docPos: UInt32,
266
+ baseFont: UIFont,
267
+ textColor: UIColor,
268
+ topLevelChildIndex: Int?,
269
+ theme: EditorTheme?
270
+ ) -> NSAttributedString {
271
+ var attrs = defaultAttributes(baseFont: baseFont, textColor: textColor)
272
+ attrs[RenderBridgeAttributes.voidNodeType] = nodeType
273
+ attrs[RenderBridgeAttributes.docPos] = docPos
274
+ attrs[.backgroundColor] = UIColor.systemGray5
275
+ if let topLevelChildIndex {
276
+ attrs[RenderBridgeAttributes.topLevelChildIndex] = NSNumber(value: topLevelChildIndex)
277
+ }
278
+
279
+ return NSAttributedString(string: "[\(label)]", attributes: attrs)
280
+ }
281
+
282
+ private static func mentionFont(from baseFont: UIFont, theme: EditorMentionNodeTheme?)
283
+ -> UIFont? {
284
+ guard let fontWeight = theme?.fontWeight else { return nil }
285
+ return EditorTextStyle(fontWeight: fontWeight).resolvedFont(fallback: baseFont)
286
+ }
287
+
288
+ }
@@ -0,0 +1,246 @@
1
+ import CryptoKit
2
+ import ImageIO
3
+ import UIKit
4
+
5
+ struct BlockContext {
6
+ let nodeType: String
7
+ let depth: UInt8
8
+ var listContext: [String: Any]?
9
+ var topLevelChildIndex: Int?
10
+ var listMarkerContext: [String: Any]?
11
+ var markerPending: Bool = false
12
+ var styleStart: Int = 0
13
+ var language: String?
14
+ }
15
+
16
+ // MARK: - HorizontalRuleAttachment
17
+
18
+ /// NSTextAttachment subclass that draws a horizontal separator line.
19
+ ///
20
+ /// The attachment renders as a thin line across the available width with
21
+ /// vertical padding. Used for `horizontalRule` void block elements.
22
+ final class HorizontalRuleAttachment: NSTextAttachment {
23
+
24
+ var styleBox: EditorStyleBox?
25
+ var lineColor: UIColor = .separator
26
+ var lineHeight: CGFloat = LayoutConstants.horizontalRuleHeight
27
+ var verticalPadding: CGFloat = LayoutConstants.horizontalRuleVerticalPadding
28
+
29
+ override func attachmentBounds(
30
+ for textContainer: NSTextContainer?,
31
+ proposedLineFragment lineFrag: CGRect,
32
+ glyphPosition position: CGPoint,
33
+ characterIndex charIndex: Int
34
+ ) -> CGRect {
35
+ let totalHeight = lineHeight + (verticalPadding * 2) + (styleBox?.inset.top ?? 0) + (styleBox?.inset.bottom ?? 0)
36
+ return CGRect(
37
+ x: 0,
38
+ y: 0,
39
+ width: lineFrag.width,
40
+ height: totalHeight
41
+ )
42
+ }
43
+
44
+ override func image(
45
+ forBounds imageBounds: CGRect,
46
+ textContainer: NSTextContainer?,
47
+ characterIndex charIndex: Int
48
+ ) -> UIImage? {
49
+ let renderer = UIGraphicsImageRenderer(bounds: imageBounds)
50
+ return renderer.image { context in
51
+ if let styleBox { styleBox.draw(in: imageBounds, context: context.cgContext); return }
52
+ lineColor.setFill()
53
+ let lineY = imageBounds.midY - (lineHeight / 2)
54
+ let lineRect = CGRect(
55
+ x: imageBounds.origin.x,
56
+ y: lineY,
57
+ width: imageBounds.width,
58
+ height: lineHeight
59
+ )
60
+ context.fill(lineRect)
61
+ }
62
+ }
63
+ }
64
+
65
+ final class AtomBlockAttachment: NSTextAttachment {
66
+ let atomKey: String
67
+ let nodeType: String
68
+ let docPos: UInt32
69
+ var reservedHeight: CGFloat
70
+
71
+ init(atomKey: String, nodeType: String, docPos: UInt32, reservedHeight: CGFloat) {
72
+ self.atomKey = atomKey
73
+ self.nodeType = nodeType
74
+ self.docPos = docPos
75
+ self.reservedHeight = reservedHeight
76
+ super.init(data: nil, ofType: nil)
77
+ }
78
+
79
+ required init?(coder: NSCoder) {
80
+ fatalError("init(coder:) has not been implemented")
81
+ }
82
+
83
+ override func attachmentBounds(
84
+ for textContainer: NSTextContainer?,
85
+ proposedLineFragment lineFrag: CGRect,
86
+ glyphPosition position: CGPoint,
87
+ characterIndex charIndex: Int
88
+ ) -> CGRect {
89
+ CGRect(x: 0, y: 0, width: lineFrag.width, height: reservedHeight)
90
+ }
91
+
92
+ override func image(
93
+ forBounds imageBounds: CGRect,
94
+ textContainer: NSTextContainer?,
95
+ characterIndex charIndex: Int
96
+ ) -> UIImage? {
97
+ nil
98
+ }
99
+ }
100
+
101
+ final class BlockImageAttachment: NSTextAttachment {
102
+ var styleBox: EditorStyleBox?
103
+ let source: String
104
+ let placeholderTint: UIColor
105
+ private weak var loadOwner: RenderImageLoadOwner?
106
+ private var loadReceipt: RenderImageLoadOwner.ImageLoadReceipt?
107
+ var preferredWidth: CGFloat?
108
+ var preferredHeight: CGFloat?
109
+ private var loadedImage: UIImage?
110
+
111
+ init(
112
+ source: String,
113
+ placeholderTint: UIColor,
114
+ preferredWidth: CGFloat?,
115
+ preferredHeight: CGFloat?
116
+ ) {
117
+ self.source = source
118
+ self.placeholderTint = placeholderTint
119
+ self.preferredWidth = preferredWidth
120
+ self.preferredHeight = preferredHeight
121
+ self.loadOwner = RenderImageLoadOwner.current
122
+ super.init(data: nil, ofType: nil)
123
+ loadImageIfNeeded()
124
+ }
125
+
126
+ required init?(coder: NSCoder) {
127
+ return nil
128
+ }
129
+
130
+ deinit {
131
+ loadReceipt?.cancel()
132
+ }
133
+
134
+ func setPreferredSize(width: CGFloat, height: CGFloat) {
135
+ preferredWidth = width
136
+ preferredHeight = height
137
+ }
138
+
139
+ func previewImage() -> UIImage? {
140
+ loadedImage ?? image
141
+ }
142
+
143
+ override func attachmentBounds(
144
+ for textContainer: NSTextContainer?,
145
+ proposedLineFragment lineFrag: CGRect,
146
+ glyphPosition position: CGPoint,
147
+ characterIndex charIndex: Int
148
+ ) -> CGRect {
149
+ let lineFragmentWidth = lineFrag.width.isFinite ? lineFrag.width : 0
150
+ let containerWidth = textContainer.map {
151
+ max(0, $0.size.width - ($0.lineFragmentPadding * 2))
152
+ } ?? 0
153
+ let widthCandidates = [lineFragmentWidth, containerWidth].filter { $0.isFinite && $0 > 0 }
154
+ let inset = styleBox?.inset ?? .zero
155
+ let maxWidth = styleBox == nil ? max(160, widthCandidates.min() ?? 160) : max(1, (widthCandidates.min() ?? 160) - inset.left - inset.right)
156
+ let fallbackAspectRatio = loadedImage.flatMap { image -> CGFloat? in
157
+ let imageSize = image.size
158
+ guard imageSize.width > 0, imageSize.height > 0 else { return nil }
159
+ return imageSize.height / imageSize.width
160
+ } ?? 0.56
161
+
162
+ var resolvedWidth = preferredWidth
163
+ var resolvedHeight = preferredHeight
164
+
165
+ if resolvedWidth == nil, resolvedHeight == nil, let loadedImage {
166
+ let imageSize = loadedImage.size
167
+ if imageSize.width > 0, imageSize.height > 0 {
168
+ resolvedWidth = imageSize.width
169
+ resolvedHeight = imageSize.height
170
+ }
171
+ } else if resolvedWidth == nil, let resolvedHeight {
172
+ resolvedWidth = resolvedHeight / fallbackAspectRatio
173
+ } else if resolvedHeight == nil, let resolvedWidth {
174
+ resolvedHeight = resolvedWidth * fallbackAspectRatio
175
+ }
176
+
177
+ let width = max(1, resolvedWidth ?? maxWidth)
178
+ let height = max(1, resolvedHeight ?? min(180, maxWidth * fallbackAspectRatio))
179
+ let scale = min(1, maxWidth / width)
180
+ return CGRect(x: 0, y: 0, width: width * scale + inset.left + inset.right, height: height * scale + inset.top + inset.bottom)
181
+ }
182
+
183
+ override func image(
184
+ forBounds imageBounds: CGRect,
185
+ textContainer: NSTextContainer?,
186
+ characterIndex charIndex: Int
187
+ ) -> UIImage? {
188
+ if let styleBox {
189
+ return UIGraphicsImageRenderer(bounds: imageBounds).image { renderer in
190
+ styleBox.draw(in: imageBounds, context: renderer.cgContext)
191
+ renderer.cgContext.addPath(styleBox.path(in: imageBounds, inner: true).cgPath)
192
+ renderer.cgContext.clip()
193
+ renderer.cgContext.clip(to: imageBounds.inset(by: styleBox.inset))
194
+ if let loadedImage {
195
+ loadedImage.draw(in: styleBox.imageRect(loadedImage.size, in: imageBounds))
196
+ } else {
197
+ let iconBounds = imageBounds.insetBy(dx: imageBounds.width * 0.35, dy: imageBounds.height * 0.35)
198
+ UIImage(systemName: "photo")?.withTintColor(placeholderTint, renderingMode: .alwaysOriginal).draw(in: iconBounds)
199
+ }
200
+ }
201
+ }
202
+ if let loadedImage { return loadedImage }
203
+
204
+ let renderer = UIGraphicsImageRenderer(bounds: imageBounds)
205
+ return renderer.image { _ in
206
+ let path = UIBezierPath(roundedRect: imageBounds, cornerRadius: 12)
207
+ UIColor.secondarySystemFill.setFill()
208
+ path.fill()
209
+
210
+ let iconSize = min(imageBounds.width, imageBounds.height) * 0.28
211
+ let iconOrigin = CGPoint(
212
+ x: imageBounds.midX - (iconSize / 2),
213
+ y: imageBounds.midY - (iconSize / 2)
214
+ )
215
+ let iconRect = CGRect(origin: iconOrigin, size: CGSize(width: iconSize, height: iconSize))
216
+
217
+ if #available(iOS 13.0, *) {
218
+ let config = UIImage.SymbolConfiguration(pointSize: iconSize, weight: .medium)
219
+ let icon = UIImage(systemName: "photo", withConfiguration: config)?
220
+ .withTintColor(placeholderTint.withAlphaComponent(0.7), renderingMode: .alwaysOriginal)
221
+ icon?.draw(in: iconRect)
222
+ }
223
+ }
224
+ }
225
+
226
+ private func loadImageIfNeeded() {
227
+ guard let loadOwner else { return }
228
+ let cacheKey = RenderImageCache.key(source: source, policy: loadOwner.policy)
229
+ if let cached = RenderImageCache.cache.image(forKey: cacheKey) {
230
+ loadedImage = cached
231
+ image = cached
232
+ return
233
+ }
234
+ loadReceipt = loadOwner.startImageLoad(source: source) { [weak self] image in
235
+ guard let self,
236
+ let image
237
+ else {
238
+ return
239
+ }
240
+ self.loadedImage = image
241
+ self.image = image
242
+ self.loadReceipt = nil
243
+ NotificationCenter.default.post(name: .editorImageAttachmentDidLoad, object: self)
244
+ }
245
+ }
246
+ }