@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,118 @@
1
+ #import <Foundation/Foundation.h>
2
+ #import <UIKit/UIKit.h>
3
+
4
+ #if __has_include("ReactNativeProseEditor-Swift.h")
5
+ #import "ReactNativeProseEditor-Swift.h"
6
+ #else
7
+ #error "ReactNativeProseEditor Swift compatibility header is unavailable; verify the pod module name and consumer codegen"
8
+ #endif
9
+
10
+ #include <react/renderer/components/PreparedProseViewer/PreparedProseMeasurementsManager.h>
11
+
12
+ #include <optional>
13
+
14
+ namespace facebook::react {
15
+ namespace {
16
+
17
+ NSString *StringFromStdString(const std::string &value) {
18
+ return [[NSString alloc] initWithBytes:value.data()
19
+ length:value.size()
20
+ encoding:NSUTF8StringEncoding] ?: @"";
21
+ }
22
+
23
+ NSString *OptionalStringFromStdString(const std::optional<std::string> &value) {
24
+ return value ? StringFromStdString(*value) : nil;
25
+ }
26
+
27
+ NSString *SourceKind(const PreparedProseViewerProps &props) {
28
+ return props.sourceKind == PreparedProseViewerSourceKind::Html ? @"html" : @"json";
29
+ }
30
+
31
+ } // namespace
32
+
33
+ void PreparedProseMeasurementsManager::bindLeaseLifecycle(
34
+ SurfaceId surfaceId,
35
+ Tag componentTag,
36
+ uint64_t leaseHandle,
37
+ const std::shared_ptr<PreparedProseViewerLeaseLifecycle>& leaseLifecycle) const {
38
+ if (leaseHandle == 0 || !leaseLifecycle || !leaseLifecycle->isActive()) return;
39
+ [[PREPPreparedProseLayoutRegistry sharedRegistry]
40
+ registerFabricLeaseSurfaceId:static_cast<int64_t>(surfaceId)
41
+ componentTag:static_cast<int64_t>(componentTag)
42
+ leaseHandle:leaseHandle];
43
+ leaseLifecycle->bindTerminalCleanup([
44
+ surfaceId, componentTag, leaseHandle] {
45
+ [[PREPPreparedProseLayoutRegistry sharedRegistry]
46
+ releaseFabricLeaseSurfaceId:static_cast<int64_t>(surfaceId)
47
+ componentTag:static_cast<int64_t>(componentTag)
48
+ leaseHandle:leaseHandle];
49
+ });
50
+ }
51
+
52
+ Size PreparedProseMeasurementsManager::measure(
53
+ SurfaceId surfaceId,
54
+ Tag componentTag,
55
+ const PreparedProseViewerProps &props,
56
+ Float effectiveWidth,
57
+ Float pointScaleFactor,
58
+ uint64_t attachmentRevision,
59
+ uint64_t nativeFontRevision,
60
+ double nativeFontScale,
61
+ int32_t userInterfaceStyle,
62
+ int32_t accessibilityContrast,
63
+ uint64_t fontEnvironmentRevision,
64
+ uint64_t leaseHandle,
65
+ const std::shared_ptr<PreparedProseViewerLeaseLifecycle>& leaseLifecycle) const {
66
+ @autoreleasepool {
67
+ const auto size = [[PREPPreparedProseLayoutRegistry sharedRegistry]
68
+ measureSurfaceId:static_cast<int64_t>(surfaceId)
69
+ componentTag:static_cast<int64_t>(componentTag)
70
+ leaseHandle:leaseHandle
71
+ sourceKind:SourceKind(props)
72
+ source:StringFromStdString(props.source)
73
+ configJSON:StringFromStdString(props.configJson)
74
+ themeJSON:OptionalStringFromStdString(props.themeJson)
75
+ imagePolicyJSON:OptionalStringFromStdString(props.imagePolicyJson)
76
+ imagesEnabled:props.imagesEnabled
77
+ collapsesWhenEmpty:props.collapsesWhenEmpty
78
+ attachmentRevision:attachmentRevision
79
+ nativeFontRevision:nativeFontRevision
80
+ nativeFontScale:nativeFontScale
81
+ fontEnvironmentRevision:(fontEnvironmentRevision)
82
+ userInterfaceStyle:userInterfaceStyle
83
+ accessibilityContrast:accessibilityContrast
84
+ widthPoints:effectiveWidth
85
+ scale:pointScaleFactor];
86
+ // A release may race a Yoga callback already in flight. The shadow state
87
+ // owns the lifecycle flag, so remove only this exact handle after the
88
+ // synchronous registry call if the callback lost that race.
89
+ if (leaseHandle != 0 && leaseLifecycle && !leaseLifecycle->isActive()) {
90
+ [[PREPPreparedProseLayoutRegistry sharedRegistry]
91
+ releaseFabricLeaseSurfaceId:static_cast<int64_t>(surfaceId)
92
+ componentTag:static_cast<int64_t>(componentTag)
93
+ leaseHandle:leaseHandle];
94
+ }
95
+ return {static_cast<Float>(size.width), static_cast<Float>(size.height)};
96
+ }
97
+ }
98
+
99
+ void PreparedProseMeasurementsManager::prepareFinalLayout(
100
+ SurfaceId,
101
+ Tag,
102
+ const PreparedProseViewerProps&,
103
+ int32_t,
104
+ int32_t,
105
+ int32_t,
106
+ Float,
107
+ uint64_t,
108
+ uint64_t,
109
+ double,
110
+ int32_t,
111
+ int32_t,
112
+ uint64_t,
113
+ uint64_t,
114
+ const std::shared_ptr<PreparedProseViewerLeaseLifecycle>&) const {
115
+ // The iOS component view consumes Fabric's final content frame directly.
116
+ }
117
+
118
+ } // namespace facebook::react
@@ -0,0 +1,9 @@
1
+ #import <UIKit/UIKit.h>
2
+
3
+ NS_ASSUME_NONNULL_BEGIN
4
+
5
+ @interface NativeSVGImageDecoder : NSObject
6
+ + (nullable UIImage *)decodeData:(NSData *)data maxDimension:(NSInteger)maxDimension;
7
+ @end
8
+
9
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,106 @@
1
+ #import "NativeSVGImageDecoder.h"
2
+ #import "NativeSVGPreflight.h"
3
+ #import <SVGgh/SVGRenderer.h>
4
+ #include <cmath>
5
+
6
+ static CGFloat SVGLength(NSString *value) {
7
+ if (!value.length) return NAN;
8
+ NSScanner *scanner = [NSScanner scannerWithString:value];
9
+ scanner.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
10
+ double number;
11
+ if (![scanner scanDouble:&number] || !std::isfinite(number)) return NAN;
12
+ NSString *unit = [[value substringFromIndex:scanner.scanLocation]
13
+ stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet].lowercaseString;
14
+ NSDictionary<NSString *, NSNumber *> *units = @{
15
+ @"": @1, @"px": @1, @"in": @96, @"cm": @(96.0 / 2.54),
16
+ @"mm": @(96.0 / 25.4), @"q": @(96.0 / 101.6), @"pt": @(96.0 / 72), @"pc": @16
17
+ };
18
+ NSNumber *multiplier = units[unit];
19
+ return multiplier ? number * multiplier.doubleValue : NAN;
20
+ }
21
+
22
+ static BOOL SVGViewBox(NSString *value, CGRect *rect) {
23
+ NSScanner *scanner = [NSScanner scannerWithString:value];
24
+ scanner.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
25
+ scanner.charactersToBeSkipped = [NSCharacterSet characterSetWithCharactersInString:@" ,\t\r\n"];
26
+ double numbers[4];
27
+ for (NSUInteger i = 0; i < 4; i++) {
28
+ if (![scanner scanDouble:&numbers[i]] || !std::isfinite(numbers[i])) return NO;
29
+ }
30
+ if (!scanner.isAtEnd || numbers[2] <= 0 || numbers[3] <= 0) return NO;
31
+ *rect = CGRectMake(numbers[0], numbers[1], numbers[2], numbers[3]);
32
+ return YES;
33
+ }
34
+
35
+ @implementation NativeSVGImageDecoder
36
+
37
+ + (UIImage *)decodeData:(NSData *)data maxDimension:(NSInteger)maxDimension {
38
+ if (maxDimension <= 0 || maxDimension > 8192) return nil;
39
+ NSArray<NSString *> *resourceIdentifiers;
40
+ NSData *sanitized = [NativeSVGPreflight sanitizedData:data resourceIdentifiers:&resourceIdentifiers];
41
+ if (!sanitized) return nil;
42
+ @try {
43
+ SVGRenderer *svg = [[SVGRenderer alloc] initWithInputStream:[NSInputStream inputStreamWithData:sanitized]];
44
+ if (!svg || svg.parserError) return nil;
45
+ for (NSString *identifier in resourceIdentifiers) {
46
+ id resource = [svg objectNamed:identifier];
47
+ if ([resource respondsToSelector:@selector(getClippingTypeWithSVGContext:)]) {
48
+ ClippingType type = [(id<GHRenderable>)resource getClippingTypeWithSVGContext:svg];
49
+ if (type == kMixedClippingType || type == kFontGlyphClippingType || type == kImageClipplingType) return nil;
50
+ }
51
+ }
52
+ NSDictionary *attributes = svg.attributes;
53
+ CGRect viewBox = CGRectZero;
54
+ BOOL hasViewBox = [attributes[@"viewBox"] length] > 0;
55
+ if (hasViewBox && !SVGViewBox(attributes[@"viewBox"], &viewBox)) return nil;
56
+ CGFloat width = SVGLength(attributes[@"width"]);
57
+ CGFloat height = SVGLength(attributes[@"height"]);
58
+ if ((!std::isnan(width) && width <= 0) || (!std::isnan(height) && height <= 0)) return nil;
59
+ if (std::isnan(width)) {
60
+ width = hasViewBox ? (std::isnan(height) ? viewBox.size.width : height * viewBox.size.width / viewBox.size.height) : 300;
61
+ }
62
+ if (std::isnan(height)) {
63
+ height = hasViewBox ? width * viewBox.size.height / viewBox.size.width : 150;
64
+ }
65
+ if (!std::isfinite(width) || !std::isfinite(height) || width <= 0 || height <= 0) return nil;
66
+ if (!hasViewBox) viewBox = CGRectMake(0, 0, width, height);
67
+ CGFloat ratio = MIN(1, maxDimension / MAX(width, height));
68
+ CGSize size = CGSizeMake(
69
+ MAX(1, MIN(maxDimension, std::floor(width * ratio))),
70
+ MAX(1, MIN(maxDimension, std::floor(height * ratio)))
71
+ );
72
+ NSArray<NSString *> *parts = [attributes[@"preserveAspectRatio"] componentsSeparatedByCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
73
+ NSMutableArray<NSString *> *tokens = [NSMutableArray array];
74
+ for (NSString *part in parts) if (part.length && ![part isEqualToString:@"defer"]) [tokens addObject:part];
75
+ NSString *alignment = tokens.firstObject ?: @"xMidYMid";
76
+ BOOL stretch = [alignment isEqualToString:@"none"];
77
+ BOOL slice = tokens.count > 1 && [tokens[1] isEqualToString:@"slice"];
78
+ CGFloat scaleX = width / viewBox.size.width, scaleY = height / viewBox.size.height;
79
+ if (!stretch) scaleX = scaleY = slice ? MAX(scaleX, scaleY) : MIN(scaleX, scaleY);
80
+ CGFloat alignX = [alignment hasPrefix:@"xMin"] ? 0 : ([alignment hasPrefix:@"xMax"] ? 1 : 0.5);
81
+ CGFloat alignY = [alignment hasSuffix:@"YMin"] ? 0 : ([alignment hasSuffix:@"YMax"] ? 1 : 0.5);
82
+ CGFloat offsetX = stretch ? 0 : (width - viewBox.size.width * scaleX) * alignX;
83
+ CGFloat offsetY = stretch ? 0 : (height - viewBox.size.height * scaleY) * alignY;
84
+ CGAffineTransform transform = CGAffineTransformMake(
85
+ scaleX * size.width / width, 0, 0, scaleY * size.height / height,
86
+ (offsetX - viewBox.origin.x * scaleX) * size.width / width,
87
+ (offsetY - viewBox.origin.y * scaleY) * size.height / height
88
+ );
89
+ if (!std::isfinite(transform.a) || !std::isfinite(transform.d) ||
90
+ !std::isfinite(transform.tx) || !std::isfinite(transform.ty)) return nil;
91
+ UIGraphicsImageRendererFormat *format = [[UIGraphicsImageRendererFormat alloc] init];
92
+ format.scale = 1;
93
+ format.opaque = NO;
94
+ format.preferredRange = UIGraphicsImageRendererFormatRangeStandard;
95
+ UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:size format:format];
96
+ return [renderer imageWithActions:^(UIGraphicsImageRendererContext *context) {
97
+ CGContextClipToRect(context.CGContext, CGRectMake(0, 0, size.width, size.height));
98
+ CGContextConcatCTM(context.CGContext, transform);
99
+ [svg renderIntoContext:context.CGContext];
100
+ }];
101
+ } @catch (NSException *exception) {
102
+ return nil;
103
+ }
104
+ }
105
+
106
+ @end
@@ -0,0 +1,11 @@
1
+ #import <Foundation/Foundation.h>
2
+
3
+ NS_ASSUME_NONNULL_BEGIN
4
+
5
+ @interface NativeSVGPreflight : NSObject
6
+ + (nullable NSData *)sanitizedData:(NSData *)data;
7
+ + (nullable NSData *)sanitizedData:(NSData *)data
8
+ resourceIdentifiers:(NSArray<NSString *> * _Nullable * _Nullable)resourceIdentifiers;
9
+ @end
10
+
11
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,219 @@
1
+ #import "NativeSVGPreflight.h"
2
+
3
+ static const NSUInteger SVGMaxNodes = 8192;
4
+ static const NSUInteger SVGMaxDepth = 128;
5
+ static const NSUInteger SVGMaxBytes = 20 * 1024 * 1024;
6
+
7
+ @interface NativeSVGPreflight () <NSXMLParserDelegate>
8
+ @property(nonatomic) NSMutableData *output;
9
+ @property(nonatomic) NSMutableArray<NSMutableArray<NSNumber *> *> *edges;
10
+ @property(nonatomic) NSMutableArray<NSMutableArray<NSString *> *> *references;
11
+ @property(nonatomic) NSMutableDictionary<NSString *, NSNumber *> *identifiers;
12
+ @property(nonatomic) NSMutableOrderedSet<NSString *> *resourceIdentifiers;
13
+ @property(nonatomic) NSMutableArray<NSNumber *> *stack;
14
+ @property(nonatomic) NSUInteger byteLimit;
15
+ @property(nonatomic) NSUInteger referenceCount;
16
+ @property(nonatomic) NSMutableString *styleText;
17
+ @property(nonatomic) BOOL rejected;
18
+ @end
19
+
20
+ @implementation NativeSVGPreflight
21
+
22
+ + (NSData *)sanitizedData:(NSData *)data {
23
+ return [self sanitizedData:data resourceIdentifiers:nil];
24
+ }
25
+
26
+ + (NSData *)sanitizedData:(NSData *)data resourceIdentifiers:(NSArray<NSString *> **)resourceIdentifiers {
27
+ if (resourceIdentifiers) *resourceIdentifiers = nil;
28
+ if (data.length == 0 || data.length > SVGMaxBytes) return nil;
29
+ const uint8_t *bytes = (const uint8_t *)data.bytes;
30
+ NSStringEncoding encoding = NSUTF8StringEncoding;
31
+ if (data.length >= 4 && ((bytes[0] == 0 && bytes[1] == 0 && bytes[2] == 0xfe && bytes[3] == 0xff) ||
32
+ (bytes[0] == 0xff && bytes[1] == 0xfe && bytes[2] == 0 && bytes[3] == 0))) {
33
+ encoding = NSUTF32StringEncoding;
34
+ } else if (data.length >= 2 && ((bytes[0] == 0xff && bytes[1] == 0xfe) || (bytes[0] == 0xfe && bytes[1] == 0xff))) {
35
+ encoding = NSUTF16StringEncoding;
36
+ }
37
+ NSString *source = [[NSString alloc] initWithData:data encoding:encoding];
38
+ if (!source || [source rangeOfString:[NSString stringWithFormat:@"%C", (unichar)0]].location != NSNotFound || [source rangeOfString:@"<!DOCTYPE" options:NSCaseInsensitiveSearch].location != NSNotFound ||
39
+ [source rangeOfString:@"<!ENTITY" options:NSCaseInsensitiveSearch].location != NSNotFound) return nil;
40
+
41
+ NativeSVGPreflight *guard = [NativeSVGPreflight new];
42
+ guard.output = [NSMutableData data];
43
+ guard.edges = [NSMutableArray array];
44
+ guard.references = [NSMutableArray array];
45
+ guard.identifiers = [NSMutableDictionary dictionary];
46
+ guard.resourceIdentifiers = [NSMutableOrderedSet orderedSet];
47
+ guard.stack = [NSMutableArray array];
48
+ guard.byteLimit = MIN(SVGMaxBytes, data.length * 8 + 1024);
49
+ NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
50
+ parser.shouldResolveExternalEntities = NO;
51
+ parser.shouldProcessNamespaces = NO;
52
+ parser.delegate = guard;
53
+ if (![parser parse] || guard.rejected || guard.edges.count == 0 || guard.stack.count != 0) return nil;
54
+ for (NSUInteger i = 0; i < guard.references.count; i++) {
55
+ for (NSString *identifier in guard.references[i]) {
56
+ NSNumber *target = guard.identifiers[identifier];
57
+ if (!target) return nil;
58
+ [guard.edges[i] addObject:target];
59
+ }
60
+ }
61
+ NSMutableData *states = [NSMutableData dataWithLength:guard.edges.count];
62
+ NSMutableData *costs = [NSMutableData dataWithLength:guard.edges.count * sizeof(NSUInteger)];
63
+ NSMutableData *depths = [NSMutableData dataWithLength:guard.edges.count * sizeof(NSUInteger)];
64
+ if (![guard visit:0 states:(uint8_t *)states.mutableBytes costs:(NSUInteger *)costs.mutableBytes
65
+ depths:(NSUInteger *)depths.mutableBytes level:1]) return nil;
66
+ if (resourceIdentifiers) *resourceIdentifiers = guard.resourceIdentifiers.array;
67
+ return [guard.output copy];
68
+ }
69
+
70
+ - (BOOL)visit:(NSUInteger)node states:(uint8_t *)states costs:(NSUInteger *)costs
71
+ depths:(NSUInteger *)depths level:(NSUInteger)level {
72
+ if (level > SVGMaxDepth || states[node] == 1) return NO;
73
+ if (states[node] == 2) return YES;
74
+ states[node] = 1;
75
+ NSUInteger cost = 1, depth = 1;
76
+ for (NSNumber *edge in self.edges[node]) {
77
+ NSUInteger child = edge.unsignedIntegerValue;
78
+ if (![self visit:child states:states costs:costs depths:depths level:level + 1]) return NO;
79
+ cost += costs[child];
80
+ depth = MAX(depth, depths[child] + 1);
81
+ if (cost > SVGMaxNodes || depth > SVGMaxDepth) return NO;
82
+ }
83
+ costs[node] = cost;
84
+ depths[node] = depth;
85
+ states[node] = 2;
86
+ return YES;
87
+ }
88
+
89
+ - (void)reject:(NSXMLParser *)parser {
90
+ self.rejected = YES;
91
+ [parser abortParsing];
92
+ }
93
+
94
+ - (void)append:(NSString *)string parser:(NSXMLParser *)parser {
95
+ NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
96
+ if (!data || data.length > self.byteLimit - self.output.length) {
97
+ [self reject:parser];
98
+ return;
99
+ }
100
+ [self.output appendData:data];
101
+ }
102
+
103
+ - (NSString *)escaped:(NSString *)value {
104
+ return [[[[value stringByReplacingOccurrencesOfString:@"&" withString:@"&amp;"]
105
+ stringByReplacingOccurrencesOfString:@"<" withString:@"&lt;"]
106
+ stringByReplacingOccurrencesOfString:@">" withString:@"&gt;"]
107
+ stringByReplacingOccurrencesOfString:@"\"" withString:@"&quot;"];
108
+ }
109
+
110
+ - (BOOL)checkValue:(NSString *)value node:(NSUInteger)node allowURLs:(BOOL)allowURLs {
111
+ if ([value rangeOfString:@"\\"].location != NSNotFound || [value rangeOfString:@"/*"].location != NSNotFound ||
112
+ [value rangeOfString:@"@"].location != NSNotFound) return NO;
113
+ static NSRegularExpression *urls;
114
+ static dispatch_once_t once;
115
+ dispatch_once(&once, ^{ urls = [NSRegularExpression regularExpressionWithPattern:@"url\\s*\\(([^)]*)\\)" options:NSRegularExpressionCaseInsensitive error:nil]; });
116
+ __block BOOL valid = YES;
117
+ [urls enumerateMatchesInString:value options:0 range:NSMakeRange(0, value.length) usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop) {
118
+ if (!allowURLs || ++self.referenceCount > SVGMaxNodes) { valid = NO; *stop = YES; return; }
119
+ NSString *target = [[value substringWithRange:[match rangeAtIndex:1]] stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
120
+ if (target.length >= 2 && (([target hasPrefix:@"'"] && [target hasSuffix:@"'"]) ||
121
+ ([target hasPrefix:@"\""] && [target hasSuffix:@"\""]))) {
122
+ target = [target substringWithRange:NSMakeRange(1, target.length - 2)];
123
+ }
124
+ if (![target hasPrefix:@"#"] || target.length < 2) { valid = NO; *stop = YES; return; }
125
+ NSString *identifier = [target substringFromIndex:1];
126
+ [self.references[node] addObject:identifier];
127
+ [self.resourceIdentifiers addObject:identifier];
128
+ }];
129
+ if (!valid) return NO;
130
+ NSString *remaining = [urls stringByReplacingMatchesInString:value options:0 range:NSMakeRange(0, value.length) withTemplate:@""];
131
+ return [remaining rangeOfString:@"url\\s*\\(" options:NSRegularExpressionSearch | NSCaseInsensitiveSearch].location == NSNotFound;
132
+ }
133
+
134
+ - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)element namespaceURI:(NSString *)namespaceURI
135
+ qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary<NSString *, NSString *> *)attributes {
136
+ static NSSet<NSString *> *allowed;
137
+ static dispatch_once_t once;
138
+ dispatch_once(&once, ^{ allowed = [NSSet setWithArray:@[@"svg", @"g", @"defs", @"symbol", @"use", @"path", @"rect", @"circle", @"ellipse", @"line", @"polyline", @"polygon", @"text", @"tspan", @"textPath", @"linearGradient", @"radialGradient", @"stop", @"pattern", @"clipPath", @"mask", @"style", @"title", @"desc"]]; });
139
+ NSString *local = [element componentsSeparatedByString:@":"].lastObject;
140
+ if (self.styleText || ![allowed containsObject:local] || self.edges.count >= SVGMaxNodes || self.stack.count >= SVGMaxDepth ||
141
+ (self.edges.count == 0 && ![local isEqualToString:@"svg"])) {
142
+ [self reject:parser]; return;
143
+ }
144
+ NSUInteger node = self.edges.count;
145
+ [self.edges addObject:[NSMutableArray array]];
146
+ [self.references addObject:[NSMutableArray array]];
147
+ if (self.stack.count) [self.edges[self.stack.lastObject.unsignedIntegerValue] addObject:@(node)];
148
+ [self.stack addObject:@(node)];
149
+ if ([local isEqualToString:@"style"]) self.styleText = [NSMutableString string];
150
+ [self append:[@"<" stringByAppendingString:element] parser:parser];
151
+ NSMutableDictionary<NSString *, NSString *> *normalized = [attributes mutableCopy];
152
+ if (normalized[@"href"]) {
153
+ normalized[@"xlink:href"] = normalized[@"href"];
154
+ [normalized removeObjectForKey:@"href"];
155
+ }
156
+ if (node == 0 || normalized[@"xmlns:xlink"]) normalized[@"xmlns:xlink"] = @"http://www.w3.org/1999/xlink";
157
+ for (NSString *name in normalized) {
158
+ NSString *key = [name componentsSeparatedByString:@":"].lastObject.lowercaseString;
159
+ NSString *value = normalized[name];
160
+ BOOL declaration = [name isEqualToString:@"xmlns"] || [name hasPrefix:@"xmlns:"];
161
+ BOOL literal = [@[@"id", @"href", @"title", @"class", @"aria-label"] containsObject:key] || [key hasPrefix:@"data-"];
162
+ if (!declaration && ([key hasPrefix:@"on"] || [key isEqualToString:@"base"] ||
163
+ (!literal && ![self checkValue:value node:node allowURLs:YES]))) {
164
+ [self reject:parser]; return;
165
+ }
166
+ if ([key isEqualToString:@"href"]) {
167
+ if (++self.referenceCount > SVGMaxNodes || ![value hasPrefix:@"#"] || value.length < 2) { [self reject:parser]; return; }
168
+ [self.references[node] addObject:[value substringFromIndex:1]];
169
+ }
170
+ if ([key isEqualToString:@"id"]) {
171
+ if (value.length == 0 || self.identifiers[value]) { [self reject:parser]; return; }
172
+ self.identifiers[value] = @(node);
173
+ }
174
+ [self append:[NSString stringWithFormat:@" %@=\"%@\"", name, [self escaped:value]] parser:parser];
175
+ if (self.rejected) return;
176
+ }
177
+ [self append:@">" parser:parser];
178
+ }
179
+
180
+ - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)element namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName {
181
+ if (self.styleText) {
182
+ if (![self checkValue:self.styleText node:self.stack.lastObject.unsignedIntegerValue allowURLs:NO]) {
183
+ [self reject:parser]; return;
184
+ }
185
+ self.styleText = nil;
186
+ }
187
+ [self append:[NSString stringWithFormat:@"</%@>", element] parser:parser];
188
+ [self.stack removeLastObject];
189
+ }
190
+
191
+ - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
192
+ if (self.styleText) [self.styleText appendString:string];
193
+ [self append:[self escaped:string] parser:parser];
194
+ }
195
+
196
+ - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock {
197
+ NSString *text = [[NSString alloc] initWithData:CDATABlock encoding:NSUTF8StringEncoding];
198
+ if (!text) { [self reject:parser]; return; }
199
+ [self parser:parser foundCharacters:text];
200
+ }
201
+
202
+ - (void)parser:(NSXMLParser *)parser foundProcessingInstructionWithTarget:(NSString *)target data:(NSString *)data {
203
+ [self reject:parser];
204
+ }
205
+
206
+ - (void)parser:(NSXMLParser *)parser foundInternalEntityDeclarationWithName:(NSString *)name value:(NSString *)value {
207
+ [self reject:parser];
208
+ }
209
+
210
+ - (void)parser:(NSXMLParser *)parser foundExternalEntityDeclarationWithName:(NSString *)name publicID:(NSString *)publicID systemID:(NSString *)systemID {
211
+ [self reject:parser];
212
+ }
213
+
214
+ - (NSData *)parser:(NSXMLParser *)parser resolveExternalEntityName:(NSString *)name systemID:(NSString *)systemID {
215
+ [self reject:parser];
216
+ return nil;
217
+ }
218
+
219
+ @end