@mathers101/react-native-render-rich-text 0.0.0-stage → 0.1.10

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 (358) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +140 -3
  3. package/ReactNativeRenderRichText.podspec +23 -0
  4. package/android/build.gradle +86 -0
  5. package/android/consumer-rules.pro +3 -0
  6. package/android/src/main/AndroidManifest.xml +2 -0
  7. package/android/src/main/cpp/jni-adapter.cpp +191 -0
  8. package/android/src/main/java/com/renderrichtext/EnrichedTiptapText.kt +673 -0
  9. package/android/src/main/java/com/renderrichtext/EnrichedTiptapTextLayoutManager.kt +24 -0
  10. package/android/src/main/java/com/renderrichtext/EnrichedTiptapTextManager.kt +405 -0
  11. package/android/src/main/java/com/renderrichtext/EnrichedTiptapTextPackage.kt +13 -0
  12. package/android/src/main/java/com/renderrichtext/MeasurementStore.kt +644 -0
  13. package/android/src/main/java/com/renderrichtext/accessibility/AccessibilityLabels.kt +17 -0
  14. package/android/src/main/java/com/renderrichtext/accessibility/AccessibleTiptapTextView.kt +112 -0
  15. package/android/src/main/java/com/renderrichtext/accessibility/TiptapAccessibilityHelper.kt +576 -0
  16. package/android/src/main/java/com/renderrichtext/events/CodeBlockPressEvent.kt +24 -0
  17. package/android/src/main/java/com/renderrichtext/events/ContextMenuItemPressEvent.kt +28 -0
  18. package/android/src/main/java/com/renderrichtext/events/CopyPressEvent.kt +24 -0
  19. package/android/src/main/java/com/renderrichtext/events/FactoidPressEvent.kt +23 -0
  20. package/android/src/main/java/com/renderrichtext/events/ImagePressEvent.kt +25 -0
  21. package/android/src/main/java/com/renderrichtext/events/LatexErrorEvent.kt +29 -0
  22. package/android/src/main/java/com/renderrichtext/events/LinkLongPressEvent.kt +23 -0
  23. package/android/src/main/java/com/renderrichtext/events/LinkPressEvent.kt +23 -0
  24. package/android/src/main/java/com/renderrichtext/events/MentionLongPressEvent.kt +25 -0
  25. package/android/src/main/java/com/renderrichtext/events/MentionPressEvent.kt +25 -0
  26. package/android/src/main/java/com/renderrichtext/events/TaskListItemPressEvent.kt +26 -0
  27. package/android/src/main/java/com/renderrichtext/math/LatexErrorReporter.kt +9 -0
  28. package/android/src/main/java/com/renderrichtext/parser/Parser.kt +59 -0
  29. package/android/src/main/java/com/renderrichtext/parser/TextLinkMatching.kt +35 -0
  30. package/android/src/main/java/com/renderrichtext/parser/TiptapASTNode.kt +69 -0
  31. package/android/src/main/java/com/renderrichtext/renderer/BaselineShiftRenderer.kt +45 -0
  32. package/android/src/main/java/com/renderrichtext/renderer/BlankLineRenderer.kt +39 -0
  33. package/android/src/main/java/com/renderrichtext/renderer/BlockStyleContext.kt +181 -0
  34. package/android/src/main/java/com/renderrichtext/renderer/BlockquoteRenderer.kt +243 -0
  35. package/android/src/main/java/com/renderrichtext/renderer/BlockquoteTextRenderer.kt +56 -0
  36. package/android/src/main/java/com/renderrichtext/renderer/CodeBlockRenderer.kt +135 -0
  37. package/android/src/main/java/com/renderrichtext/renderer/CodeRenderer.kt +37 -0
  38. package/android/src/main/java/com/renderrichtext/renderer/EmphasisRenderer.kt +28 -0
  39. package/android/src/main/java/com/renderrichtext/renderer/FactoidRenderer.kt +97 -0
  40. package/android/src/main/java/com/renderrichtext/renderer/HeadingRenderer.kt +81 -0
  41. package/android/src/main/java/com/renderrichtext/renderer/HighlightRenderer.kt +26 -0
  42. package/android/src/main/java/com/renderrichtext/renderer/LineBreakRenderer.kt +17 -0
  43. package/android/src/main/java/com/renderrichtext/renderer/LinkRenderer.kt +90 -0
  44. package/android/src/main/java/com/renderrichtext/renderer/ListContextManager.kt +109 -0
  45. package/android/src/main/java/com/renderrichtext/renderer/ListItemRenderer.kt +211 -0
  46. package/android/src/main/java/com/renderrichtext/renderer/ListRenderer.kt +133 -0
  47. package/android/src/main/java/com/renderrichtext/renderer/MentionRenderer.kt +85 -0
  48. package/android/src/main/java/com/renderrichtext/renderer/NodeRenderer.kt +207 -0
  49. package/android/src/main/java/com/renderrichtext/renderer/ParagraphRenderer.kt +91 -0
  50. package/android/src/main/java/com/renderrichtext/renderer/Renderer.kt +148 -0
  51. package/android/src/main/java/com/renderrichtext/renderer/SoftBreakRenderer.kt +17 -0
  52. package/android/src/main/java/com/renderrichtext/renderer/SpanStyleCache.kt +143 -0
  53. package/android/src/main/java/com/renderrichtext/renderer/StrikethroughRenderer.kt +28 -0
  54. package/android/src/main/java/com/renderrichtext/renderer/StrongRenderer.kt +28 -0
  55. package/android/src/main/java/com/renderrichtext/renderer/TextRenderer.kt +31 -0
  56. package/android/src/main/java/com/renderrichtext/renderer/ThematicBreakRenderer.kt +46 -0
  57. package/android/src/main/java/com/renderrichtext/renderer/UnderlineRenderer.kt +28 -0
  58. package/android/src/main/java/com/renderrichtext/spans/BaseListSpan.kt +164 -0
  59. package/android/src/main/java/com/renderrichtext/spans/BaselineShiftSpan.kt +27 -0
  60. package/android/src/main/java/com/renderrichtext/spans/BlockquoteSpan.kt +302 -0
  61. package/android/src/main/java/com/renderrichtext/spans/CodeBackgroundSpan.kt +205 -0
  62. package/android/src/main/java/com/renderrichtext/spans/CodeBlockSpan.kt +216 -0
  63. package/android/src/main/java/com/renderrichtext/spans/CodeSpan.kt +32 -0
  64. package/android/src/main/java/com/renderrichtext/spans/EmphasisSpan.kt +42 -0
  65. package/android/src/main/java/com/renderrichtext/spans/FactoidBackgroundSpan.kt +265 -0
  66. package/android/src/main/java/com/renderrichtext/spans/FactoidPaddingSpan.kt +258 -0
  67. package/android/src/main/java/com/renderrichtext/spans/FactoidSpan.kt +32 -0
  68. package/android/src/main/java/com/renderrichtext/spans/FadeInSpan.kt +29 -0
  69. package/android/src/main/java/com/renderrichtext/spans/HeadingSpan.kt +38 -0
  70. package/android/src/main/java/com/renderrichtext/spans/HighlightSpan.kt +80 -0
  71. package/android/src/main/java/com/renderrichtext/spans/ImageSpan.kt +481 -0
  72. package/android/src/main/java/com/renderrichtext/spans/InlineBackgroundGeometry.kt +42 -0
  73. package/android/src/main/java/com/renderrichtext/spans/LineHeightSpan.kt +39 -0
  74. package/android/src/main/java/com/renderrichtext/spans/LinkPillIconCache.kt +154 -0
  75. package/android/src/main/java/com/renderrichtext/spans/LinkPillSpan.kt +381 -0
  76. package/android/src/main/java/com/renderrichtext/spans/LinkSpan.kt +68 -0
  77. package/android/src/main/java/com/renderrichtext/spans/ListItemSpacingSpan.kt +33 -0
  78. package/android/src/main/java/com/renderrichtext/spans/ListMarkerAnchorSpan.kt +38 -0
  79. package/android/src/main/java/com/renderrichtext/spans/MarginBottomSpan.kt +76 -0
  80. package/android/src/main/java/com/renderrichtext/spans/MentionChipSpan.kt +132 -0
  81. package/android/src/main/java/com/renderrichtext/spans/MentionSpan.kt +46 -0
  82. package/android/src/main/java/com/renderrichtext/spans/OrderedListSpan.kt +127 -0
  83. package/android/src/main/java/com/renderrichtext/spans/SpoilerSpan.kt +33 -0
  84. package/android/src/main/java/com/renderrichtext/spans/StrikethroughSpan.kt +12 -0
  85. package/android/src/main/java/com/renderrichtext/spans/StrongSpan.kt +39 -0
  86. package/android/src/main/java/com/renderrichtext/spans/TaskListSpan.kt +143 -0
  87. package/android/src/main/java/com/renderrichtext/spans/TextSpan.kt +26 -0
  88. package/android/src/main/java/com/renderrichtext/spans/ThematicBreakSpan.kt +69 -0
  89. package/android/src/main/java/com/renderrichtext/spans/UnorderedListSpan.kt +96 -0
  90. package/android/src/main/java/com/renderrichtext/spoiler/SpoilerStubs.kt +46 -0
  91. package/android/src/main/java/com/renderrichtext/styles/BaseBlockStyle.kt +11 -0
  92. package/android/src/main/java/com/renderrichtext/styles/BlockquoteStyle.kt +83 -0
  93. package/android/src/main/java/com/renderrichtext/styles/CodeBlockStyle.kt +80 -0
  94. package/android/src/main/java/com/renderrichtext/styles/CodeStyle.kt +26 -0
  95. package/android/src/main/java/com/renderrichtext/styles/EmphasisStyle.kt +21 -0
  96. package/android/src/main/java/com/renderrichtext/styles/FactoidStyle.kt +21 -0
  97. package/android/src/main/java/com/renderrichtext/styles/HeadingStyle.kt +33 -0
  98. package/android/src/main/java/com/renderrichtext/styles/HighlightStyle.kt +19 -0
  99. package/android/src/main/java/com/renderrichtext/styles/ImageStyle.kt +29 -0
  100. package/android/src/main/java/com/renderrichtext/styles/InlineImageStyle.kt +17 -0
  101. package/android/src/main/java/com/renderrichtext/styles/InlineMathStyle.kt +17 -0
  102. package/android/src/main/java/com/renderrichtext/styles/LinkPillContent.kt +36 -0
  103. package/android/src/main/java/com/renderrichtext/styles/LinkPillStyle.kt +44 -0
  104. package/android/src/main/java/com/renderrichtext/styles/LinkStyle.kt +23 -0
  105. package/android/src/main/java/com/renderrichtext/styles/LinkVariantEntry.kt +34 -0
  106. package/android/src/main/java/com/renderrichtext/styles/ListStyle.kt +65 -0
  107. package/android/src/main/java/com/renderrichtext/styles/MathStyle.kt +29 -0
  108. package/android/src/main/java/com/renderrichtext/styles/MentionStyle.kt +19 -0
  109. package/android/src/main/java/com/renderrichtext/styles/ParagraphStyle.kt +33 -0
  110. package/android/src/main/java/com/renderrichtext/styles/SpoilerStyle.kt +27 -0
  111. package/android/src/main/java/com/renderrichtext/styles/StrikethroughStyle.kt +17 -0
  112. package/android/src/main/java/com/renderrichtext/styles/StrongStyle.kt +21 -0
  113. package/android/src/main/java/com/renderrichtext/styles/StyleConfig.kt +411 -0
  114. package/android/src/main/java/com/renderrichtext/styles/StyleParser.kt +92 -0
  115. package/android/src/main/java/com/renderrichtext/styles/SubscriptStyle.kt +16 -0
  116. package/android/src/main/java/com/renderrichtext/styles/SuperscriptStyle.kt +16 -0
  117. package/android/src/main/java/com/renderrichtext/styles/TableStyle.kt +75 -0
  118. package/android/src/main/java/com/renderrichtext/styles/TaskListStyle.kt +29 -0
  119. package/android/src/main/java/com/renderrichtext/styles/TextAlignment.kt +32 -0
  120. package/android/src/main/java/com/renderrichtext/styles/ThematicBreakStyle.kt +23 -0
  121. package/android/src/main/java/com/renderrichtext/styles/UnderlineStyle.kt +17 -0
  122. package/android/src/main/java/com/renderrichtext/styles/VideoStyle.kt +31 -0
  123. package/android/src/main/java/com/renderrichtext/utils/common/BorderStyleUtils.kt +86 -0
  124. package/android/src/main/java/com/renderrichtext/utils/common/BreakStrategyUtils.kt +32 -0
  125. package/android/src/main/java/com/renderrichtext/utils/common/CodeBlockHighlighter.kt +36 -0
  126. package/android/src/main/java/com/renderrichtext/utils/common/CodeBlockNode.kt +42 -0
  127. package/android/src/main/java/com/renderrichtext/utils/common/EllipsizeUtils.kt +27 -0
  128. package/android/src/main/java/com/renderrichtext/utils/common/EnrichedTiptapAncestorUtils.kt +10 -0
  129. package/android/src/main/java/com/renderrichtext/utils/common/FeatureFlags.kt +9 -0
  130. package/android/src/main/java/com/renderrichtext/utils/common/LinkRecognitionProps.kt +31 -0
  131. package/android/src/main/java/com/renderrichtext/utils/common/LinkRegexConfig.kt +56 -0
  132. package/android/src/main/java/com/renderrichtext/utils/common/MotionPreferences.kt +18 -0
  133. package/android/src/main/java/com/renderrichtext/utils/common/ReadableMapExtensions.kt +28 -0
  134. package/android/src/main/java/com/renderrichtext/utils/common/TiptapViewManagerUtils.kt +242 -0
  135. package/android/src/main/java/com/renderrichtext/utils/common/layout/RTLUtils.kt +6 -0
  136. package/android/src/main/java/com/renderrichtext/utils/common/serialization/TiptapASTSerializer.kt +368 -0
  137. package/android/src/main/java/com/renderrichtext/utils/text/ImageCache.kt +88 -0
  138. package/android/src/main/java/com/renderrichtext/utils/text/ImageDownloader.kt +203 -0
  139. package/android/src/main/java/com/renderrichtext/utils/text/LocalImageLoader.kt +167 -0
  140. package/android/src/main/java/com/renderrichtext/utils/text/TailFadeInAnimator.kt +84 -0
  141. package/android/src/main/java/com/renderrichtext/utils/text/conversion/HTMLGenerator.kt +1105 -0
  142. package/android/src/main/java/com/renderrichtext/utils/text/conversion/TiptapExtractor.kt +423 -0
  143. package/android/src/main/java/com/renderrichtext/utils/text/extensions/ParagraphUtils.kt +9 -0
  144. package/android/src/main/java/com/renderrichtext/utils/text/extensions/SpannableExtensions.kt +9 -0
  145. package/android/src/main/java/com/renderrichtext/utils/text/extensions/TextPaintExtensions.kt +76 -0
  146. package/android/src/main/java/com/renderrichtext/utils/text/interaction/CheckboxTouchHelper.kt +61 -0
  147. package/android/src/main/java/com/renderrichtext/utils/text/interaction/TaskListTapUtils.kt +286 -0
  148. package/android/src/main/java/com/renderrichtext/utils/text/span/ApplyLineHeight.kt +39 -0
  149. package/android/src/main/java/com/renderrichtext/utils/text/span/BlockSpacing.kt +142 -0
  150. package/android/src/main/java/com/renderrichtext/utils/text/span/SpanFlags.kt +43 -0
  151. package/android/src/main/java/com/renderrichtext/utils/text/span/WidthAwareSpans.kt +30 -0
  152. package/android/src/main/java/com/renderrichtext/utils/text/view/CodeBlockPressHost.kt +15 -0
  153. package/android/src/main/java/com/renderrichtext/utils/text/view/ImagePressHost.kt +19 -0
  154. package/android/src/main/java/com/renderrichtext/utils/text/view/LinkEvents.kt +88 -0
  155. package/android/src/main/java/com/renderrichtext/utils/text/view/LinkLongPressMovementMethod.kt +449 -0
  156. package/android/src/main/java/com/renderrichtext/utils/text/view/SelectionActionMode.kt +235 -0
  157. package/android/src/main/java/com/renderrichtext/utils/text/view/TextSelectionColors.kt +48 -0
  158. package/android/src/main/java/com/renderrichtext/utils/text/view/TextViewSetup.kt +119 -0
  159. package/android/src/main/java/com/renderrichtext/views/ContextMenuPopup.kt +217 -0
  160. package/android/src/main/java/com/renderrichtext/views/CopyGlyph.kt +101 -0
  161. package/android/src/main/java/com/renderrichtext/views/WrapGlyph.kt +40 -0
  162. package/android/src/main/jni/CMakeLists.txt +52 -0
  163. package/android/src/main/jni/react/renderer/components/RichTextSpec/ComponentDescriptors.h +30 -0
  164. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextComponentDescriptor.h +29 -0
  165. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextMeasurementManager.cpp +45 -0
  166. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextMeasurementManager.h +21 -0
  167. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextShadowNode.cpp +38 -0
  168. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextShadowNode.h +53 -0
  169. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextState.cpp +9 -0
  170. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextState.h +24 -0
  171. package/android/src/main/jni/react/renderer/components/RichTextSpec/conversions.h +40 -0
  172. package/cpp/parser/TiptapASTNode.hpp +68 -0
  173. package/cpp/parser/TiptapParser.cpp +233 -0
  174. package/cpp/parser/TiptapParser.hpp +13 -0
  175. package/cpp/vendor/nlohmann/json.hpp +24765 -0
  176. package/ios/EnrichedTiptapText.h +27 -0
  177. package/ios/EnrichedTiptapText.mm +1222 -0
  178. package/ios/attachments/ENRMImageAttachment.h +51 -0
  179. package/ios/attachments/ENRMImageAttachment.m +398 -0
  180. package/ios/attachments/ENRMLinkPillAttachment.h +47 -0
  181. package/ios/attachments/ENRMLinkPillAttachment.m +324 -0
  182. package/ios/attachments/ENRMLinkPillIconCache.h +28 -0
  183. package/ios/attachments/ENRMLinkPillIconCache.m +181 -0
  184. package/ios/attachments/ENRMLinkPillText.h +27 -0
  185. package/ios/attachments/ENRMLinkPillText.m +118 -0
  186. package/ios/attachments/ENRMMathInlineAttachment.h +7 -0
  187. package/ios/attachments/ENRMMathInlineAttachment.m +4 -0
  188. package/ios/attachments/ThematicBreakAttachment.h +15 -0
  189. package/ios/attachments/ThematicBreakAttachment.m +33 -0
  190. package/ios/internals/ENRMViewFreeMeasurement.h +208 -0
  191. package/ios/internals/EnrichedTiptapTextComponentDescriptor.h +19 -0
  192. package/ios/internals/EnrichedTiptapTextShadowNode.h +43 -0
  193. package/ios/internals/EnrichedTiptapTextShadowNode.mm +69 -0
  194. package/ios/internals/EnrichedTiptapTextState.h +24 -0
  195. package/ios/internals/MeasurementCache.h +308 -0
  196. package/ios/internals/ShadowMeasurementUtils.h +145 -0
  197. package/ios/parser/ENRMTextLinkAttributes.h +7 -0
  198. package/ios/parser/ENRMTiptapParser.h +33 -0
  199. package/ios/parser/ENRMTiptapParser.mm +73 -0
  200. package/ios/parser/TiptapASTNode.h +57 -0
  201. package/ios/parser/TiptapASTNode.m +52 -0
  202. package/ios/parser/TiptapParserBridge.mm +179 -0
  203. package/ios/renderer/AttributedRenderer.h +23 -0
  204. package/ios/renderer/AttributedRenderer.m +229 -0
  205. package/ios/renderer/BaseRenderer.h +33 -0
  206. package/ios/renderer/BaseRenderer.m +46 -0
  207. package/ios/renderer/BaselineShiftTextAttributes.h +10 -0
  208. package/ios/renderer/BaselineShiftTextAttributes.m +26 -0
  209. package/ios/renderer/BlankLineRenderer.h +4 -0
  210. package/ios/renderer/BlankLineRenderer.m +51 -0
  211. package/ios/renderer/BlockquoteRenderer.h +6 -0
  212. package/ios/renderer/BlockquoteRenderer.m +258 -0
  213. package/ios/renderer/CodeBlockRenderer.h +9 -0
  214. package/ios/renderer/CodeBlockRenderer.m +99 -0
  215. package/ios/renderer/CodeRenderer.h +9 -0
  216. package/ios/renderer/CodeRenderer.m +69 -0
  217. package/ios/renderer/ENRMBlockquoteTextRenderer.h +25 -0
  218. package/ios/renderer/ENRMBlockquoteTextRenderer.m +48 -0
  219. package/ios/renderer/EmphasisRenderer.h +5 -0
  220. package/ios/renderer/EmphasisRenderer.m +100 -0
  221. package/ios/renderer/FactoidRenderer.h +9 -0
  222. package/ios/renderer/FactoidRenderer.m +130 -0
  223. package/ios/renderer/HeadingRenderer.h +6 -0
  224. package/ios/renderer/HeadingRenderer.m +103 -0
  225. package/ios/renderer/HighlightRenderer.h +7 -0
  226. package/ios/renderer/HighlightRenderer.m +33 -0
  227. package/ios/renderer/LinkRenderer.h +6 -0
  228. package/ios/renderer/LinkRenderer.m +158 -0
  229. package/ios/renderer/ListItemRenderer.h +24 -0
  230. package/ios/renderer/ListItemRenderer.m +283 -0
  231. package/ios/renderer/ListRenderer.h +13 -0
  232. package/ios/renderer/ListRenderer.m +126 -0
  233. package/ios/renderer/MentionRenderer.h +9 -0
  234. package/ios/renderer/MentionRenderer.m +96 -0
  235. package/ios/renderer/NodeRenderer.h +8 -0
  236. package/ios/renderer/ParagraphRenderer.h +6 -0
  237. package/ios/renderer/ParagraphRenderer.m +85 -0
  238. package/ios/renderer/RenderContext.h +145 -0
  239. package/ios/renderer/RenderContext.m +403 -0
  240. package/ios/renderer/RendererFactory.h +12 -0
  241. package/ios/renderer/RendererFactory.m +158 -0
  242. package/ios/renderer/StrikethroughRenderer.h +5 -0
  243. package/ios/renderer/StrikethroughRenderer.m +30 -0
  244. package/ios/renderer/StrongRenderer.h +5 -0
  245. package/ios/renderer/StrongRenderer.m +88 -0
  246. package/ios/renderer/TextRenderer.h +6 -0
  247. package/ios/renderer/TextRenderer.m +18 -0
  248. package/ios/renderer/ThematicBreakRenderer.h +4 -0
  249. package/ios/renderer/ThematicBreakRenderer.m +42 -0
  250. package/ios/renderer/UnderlineRenderer.h +4 -0
  251. package/ios/renderer/UnderlineRenderer.m +41 -0
  252. package/ios/styles/ENRMFontSlot.h +12 -0
  253. package/ios/styles/ENRMFontSlot.m +24 -0
  254. package/ios/styles/StyleConfig.h +488 -0
  255. package/ios/styles/StyleConfig.mm +2820 -0
  256. package/ios/utils/AccessibilityInfo.h +35 -0
  257. package/ios/utils/AccessibilityInfo.m +24 -0
  258. package/ios/utils/BlockquoteBorder.h +26 -0
  259. package/ios/utils/BlockquoteBorder.m +294 -0
  260. package/ios/utils/CodeBackground.h +19 -0
  261. package/ios/utils/CodeBackground.m +197 -0
  262. package/ios/utils/CodeBlockBackground.h +17 -0
  263. package/ios/utils/CodeBlockBackground.m +103 -0
  264. package/ios/utils/ContextMenuUtils.h +76 -0
  265. package/ios/utils/ContextMenuUtils.mm +75 -0
  266. package/ios/utils/ENRMAccessibilityLabels.h +40 -0
  267. package/ios/utils/ENRMAccessibilityLabels.m +5 -0
  268. package/ios/utils/ENRMAsyncRenderCoordinator.h +24 -0
  269. package/ios/utils/ENRMAsyncRenderCoordinator.m +37 -0
  270. package/ios/utils/ENRMAtomicSize.h +65 -0
  271. package/ios/utils/ENRMCodeBlockContent.h +37 -0
  272. package/ios/utils/ENRMCodeBlockContent.mm +89 -0
  273. package/ios/utils/ENRMFeatureFlags.h +25 -0
  274. package/ios/utils/ENRMImageDownloader.h +30 -0
  275. package/ios/utils/ENRMImageDownloader.m +168 -0
  276. package/ios/utils/ENRMLatexErrorCoordinator.h +27 -0
  277. package/ios/utils/ENRMLatexErrorCoordinator.mm +75 -0
  278. package/ios/utils/ENRMLatexErrorReporting.h +13 -0
  279. package/ios/utils/ENRMLinkContextMenus.h +93 -0
  280. package/ios/utils/ENRMLinkContextMenus.m +178 -0
  281. package/ios/utils/ENRMLinkRegexConfig.h +30 -0
  282. package/ios/utils/ENRMLinkRegexConfig.mm +104 -0
  283. package/ios/utils/ENRMLinkRegexProps.h +23 -0
  284. package/ios/utils/ENRMLocalImageLoader.h +35 -0
  285. package/ios/utils/ENRMLocalImageLoader.m +111 -0
  286. package/ios/utils/ENRMMenuAction.h +27 -0
  287. package/ios/utils/ENRMMenuAction.m +33 -0
  288. package/ios/utils/ENRMSpoilerOverlayManager.h +15 -0
  289. package/ios/utils/ENRMSpoilerOverlayManager.m +19 -0
  290. package/ios/utils/ENRMSpoilerTapUtils.h +6 -0
  291. package/ios/utils/ENRMSpoilerTapUtils.m +11 -0
  292. package/ios/utils/ENRMTailFadeInAnimator.h +16 -0
  293. package/ios/utils/ENRMTailFadeInAnimator.m +161 -0
  294. package/ios/utils/ENRMTextHitTest.h +23 -0
  295. package/ios/utils/ENRMTextHitTest.m +20 -0
  296. package/ios/utils/ENRMTextInteractionUtils.h +20 -0
  297. package/ios/utils/ENRMTextInteractionUtils.m +15 -0
  298. package/ios/utils/ENRMTextRenderer.h +38 -0
  299. package/ios/utils/ENRMTextRenderer.m +54 -0
  300. package/ios/utils/ENRMTextViewSetup.h +132 -0
  301. package/ios/utils/ENRMUIKit.h +429 -0
  302. package/ios/utils/EditMenuUtils.h +105 -0
  303. package/ios/utils/EditMenuUtils.m +143 -0
  304. package/ios/utils/FactoidBackground.h +20 -0
  305. package/ios/utils/FactoidBackground.m +161 -0
  306. package/ios/utils/FontScaleObserver.h +10 -0
  307. package/ios/utils/FontScaleObserver.m +55 -0
  308. package/ios/utils/FontUtils.h +31 -0
  309. package/ios/utils/FontUtils.m +63 -0
  310. package/ios/utils/HTMLGenerator.h +25 -0
  311. package/ios/utils/HTMLGenerator.m +1041 -0
  312. package/ios/utils/HeightUpdateUtils.h +25 -0
  313. package/ios/utils/ImageRequestHeaderUtils.h +35 -0
  314. package/ios/utils/LastElementUtils.h +97 -0
  315. package/ios/utils/LinkContextMenuUtils.h +55 -0
  316. package/ios/utils/LinkPillContentUtils.h +46 -0
  317. package/ios/utils/LinkTapUtils.h +56 -0
  318. package/ios/utils/LinkTapUtils.m +139 -0
  319. package/ios/utils/ListMarkerDrawer.h +15 -0
  320. package/ios/utils/ListMarkerDrawer.m +239 -0
  321. package/ios/utils/MentionBackground.h +26 -0
  322. package/ios/utils/MentionBackground.m +86 -0
  323. package/ios/utils/ParagraphStyleUtils.h +87 -0
  324. package/ios/utils/ParagraphStyleUtils.m +484 -0
  325. package/ios/utils/PasteboardUtils.h +48 -0
  326. package/ios/utils/PasteboardUtils.m +166 -0
  327. package/ios/utils/RTFExportUtils.h +24 -0
  328. package/ios/utils/RTFExportUtils.m +299 -0
  329. package/ios/utils/RuntimeKeys.h +44 -0
  330. package/ios/utils/RuntimeKeys.m +13 -0
  331. package/ios/utils/SelectionColorUtils.h +14 -0
  332. package/ios/utils/StylePropsUtils.h +1340 -0
  333. package/ios/utils/TaskListTapUtils.h +6 -0
  334. package/ios/utils/TaskListTapUtils.m +14 -0
  335. package/ios/utils/TextViewLayoutManager.h +14 -0
  336. package/ios/utils/TextViewLayoutManager.mm +198 -0
  337. package/ios/utils/TiptapAccessibilityElementBuilder.h +43 -0
  338. package/ios/utils/TiptapAccessibilityElementBuilder.m +432 -0
  339. package/ios/utils/TiptapExtractor.h +17 -0
  340. package/ios/utils/TiptapExtractor.m +367 -0
  341. package/ios/views/ENRMTiptapTextView.h +25 -0
  342. package/ios/views/ENRMTiptapTextView.m +247 -0
  343. package/package.json +70 -6
  344. package/react-native.config.js +10 -0
  345. package/src/EnrichedTiptapTextNativeComponent.ts +739 -0
  346. package/src/RichText.tsx +164 -0
  347. package/src/admonitionDefaults.ts +58 -0
  348. package/src/darkModeTextStyle.ts +99 -0
  349. package/src/headingDefaults.ts +21 -0
  350. package/src/index.tsx +4 -0
  351. package/src/linkVariantUtils.ts +120 -0
  352. package/src/normalizeTiptapStyle.ts +397 -0
  353. package/src/rn-globals.d.ts +1 -0
  354. package/src/styleUtils.ts +107 -0
  355. package/src/types/TiptapStyle.ts +532 -0
  356. package/src/types/TiptapStyleInternal.ts +299 -0
  357. package/src/types/linkPill.ts +9 -0
  358. package/src/utils/isDev.ts +4 -0
@@ -0,0 +1,145 @@
1
+ #import "ENRMLatexErrorReporting.h"
2
+ #import "ENRMUIKit.h"
3
+ #import <Foundation/Foundation.h>
4
+
5
+ typedef NS_ENUM(NSInteger, BlockType) {
6
+ BlockTypeNone,
7
+ BlockTypeParagraph,
8
+ BlockTypeHeading,
9
+ BlockTypeBlockquote,
10
+ BlockTypeUnorderedList,
11
+ BlockTypeOrderedList,
12
+ BlockTypeCodeBlock
13
+ };
14
+
15
+ /// YES when the enclosing block re-stamps its own line height over paragraph content and applies the
16
+ /// matching baseline offset itself, so a paragraph nested inside it must not apply its own (the outer
17
+ /// block's line height wins, and applyBaselineOffset skips ranges that already carry an offset).
18
+ /// TODO: loose list items have the same shape (ParagraphRenderer runs, then the list re-stamps its
19
+ /// line height); add BlockTypeUnorderedList/BlockTypeOrderedList here once lists own their offset too.
20
+ static inline BOOL ENRMBlockTypeReappliesBaselineOffset(BlockType type)
21
+ {
22
+ return type == BlockTypeBlockquote;
23
+ }
24
+
25
+ typedef NS_ENUM(NSInteger, ListType) { ListTypeUnordered, ListTypeOrdered };
26
+
27
+ @interface BlockStyle : NSObject
28
+ @property (nonatomic, assign) CGFloat fontSize;
29
+ @property (nonatomic, strong) NSString *fontFamily;
30
+ @property (nonatomic, strong) NSString *fontWeight;
31
+ @property (nonatomic, strong) RCTUIColor *color;
32
+ @property (nonatomic, strong) UIFont *cachedFont;
33
+ @property (nonatomic, strong) NSDictionary *cachedTextAttributes;
34
+ @end
35
+
36
+ @interface RenderContext : NSObject
37
+ @property (nonatomic, strong) NSMutableArray<NSValue *> *linkRanges;
38
+ @property (nonatomic, strong) NSMutableArray<NSString *> *linkURLs;
39
+ @property (nonatomic, strong) NSMutableArray<NSValue *> *headingRanges;
40
+ @property (nonatomic, strong) NSMutableArray<NSNumber *> *headingLevels;
41
+ @property (nonatomic, strong) NSMutableArray<NSValue *> *imageRanges;
42
+ @property (nonatomic, strong) NSMutableArray<NSString *> *imageAltTexts;
43
+ @property (nonatomic, strong) NSMutableArray<NSString *> *imageURLs;
44
+ @property (nonatomic, strong) NSMutableArray<NSValue *> *listItemRanges;
45
+ @property (nonatomic, strong) NSMutableArray<NSNumber *> *listItemPositions; // Position in parent list (1, 2, 3...)
46
+ @property (nonatomic, strong) NSMutableArray<NSNumber *> *listItemDepths; // Nesting depth (1 = top level, 2+ = nested)
47
+ @property (nonatomic, strong) NSMutableArray<NSNumber *> *listItemOrdered; // YES = ordered, NO = unordered (bullet)
48
+ @property (nonatomic, assign) BlockType currentBlockType;
49
+ @property (nonatomic, strong) BlockStyle *currentBlockStyle;
50
+ @property (nonatomic, assign) NSInteger currentHeadingLevel;
51
+ @property (nonatomic, assign) NSInteger blockquoteDepth;
52
+ @property (nonatomic, assign) NSInteger listDepth;
53
+ @property (nonatomic, assign) ListType listType;
54
+ @property (nonatomic, assign) NSInteger listItemNumber;
55
+ @property (nonatomic, assign) CGFloat listMarkerWidth;
56
+ @property (nonatomic, assign) CGFloat listMarkerExtra;
57
+ @property (nonatomic, assign) CGFloat ancestorMarkerOffset;
58
+ @property (nonatomic, assign) CGFloat listItemMarkerExtra;
59
+ @property (nonatomic, assign) CGFloat accumulatedIndent;
60
+ @property (nonatomic, assign) BOOL allowFontScaling;
61
+ @property (nonatomic, assign) CGFloat maxFontSizeMultiplier;
62
+ @property (nonatomic, assign) NSInteger taskItemCount;
63
+ @property (nonatomic, strong) NSMutableArray<id<ENRMLatexErrorReporting>> *mathReporters;
64
+
65
+ - (instancetype)init;
66
+ - (void)reset;
67
+
68
+ - (UIFont *)cachedFontForSize:(CGFloat)fontSize family:(NSString *)fontFamily weight:(NSString *)fontWeight;
69
+ - (NSMutableParagraphStyle *)spacerStyleWithHeight:(CGFloat)height spacing:(CGFloat)spacing;
70
+ - (NSMutableParagraphStyle *)blockSpacerStyleWithMargin:(CGFloat)margin;
71
+ - (void)registerLinkRange:(NSRange)range url:(NSString *)url;
72
+
73
+ - (void)applyLinkAttributesToString:(NSMutableAttributedString *)attributedString;
74
+ - (void)applyImageAttributesToString:(NSMutableAttributedString *)attributedString;
75
+ - (void)registerHeadingRange:(NSRange)range level:(NSInteger)level text:(NSString *)text;
76
+ - (void)registerImageRange:(NSRange)range altText:(NSString *)altText url:(NSString *)url;
77
+ - (void)registerListItemRange:(NSRange)range
78
+ position:(NSInteger)position
79
+ depth:(NSInteger)depth
80
+ isOrdered:(BOOL)isOrdered;
81
+ - (void)setBlockStyle:(BlockType)type
82
+ fontSize:(CGFloat)fontSize
83
+ fontFamily:(NSString *)fontFamily
84
+ fontWeight:(NSString *)fontWeight
85
+ color:(RCTUIColor *)color;
86
+ - (void)setBlockStyle:(BlockType)type
87
+ fontSize:(CGFloat)fontSize
88
+ fontFamily:(NSString *)fontFamily
89
+ fontWeight:(NSString *)fontWeight
90
+ color:(RCTUIColor *)color
91
+ headingLevel:(NSInteger)headingLevel;
92
+ - (void)setBlockStyle:(BlockType)type
93
+ font:(UIFont *)font
94
+ color:(RCTUIColor *)color
95
+ headingLevel:(NSInteger)headingLevel;
96
+ - (BlockStyle *)getBlockStyle;
97
+ - (NSDictionary *)getTextAttributes;
98
+ - (void)clearBlockStyle;
99
+
100
+ /**
101
+ * Captures/restores the scoped context state: block style, block type, heading level,
102
+ * blockquote/list depths, list type, list item counter and accumulated indent.
103
+ * Accumulators (range registries, taskItemCount) are excluded on purpose — they
104
+ * must survive restores.
105
+ */
106
+ - (id)snapshotScope;
107
+ - (void)restoreScope:(id)snapshot;
108
+
109
+ /**
110
+ * Checks if colors should be preserved based on existing attributes.
111
+ * Returns YES if the text is inside a link or inline code, which means
112
+ * we should preserve their colors instead of applying new colors.
113
+ */
114
+ + (BOOL)shouldPreserveColors:(NSDictionary *)existingAttributes;
115
+
116
+ /**
117
+ * Calculates the color that strong would use based on the configured strong color and block style.
118
+ * Uses strongColor if explicitly set (different from block color), otherwise uses block color.
119
+ */
120
+ + (RCTUIColor *)calculateStrongColor:(RCTUIColor *)configStrongColor blockColor:(RCTUIColor *)blockColor;
121
+
122
+ /**
123
+ * Resolves highlight foreground color: uses block color when config matches paragraph default.
124
+ */
125
+ + (RCTUIColor *)calculateHighlightColor:(RCTUIColor *)configHighlightColor
126
+ paragraphColor:(RCTUIColor *)paragraphColor
127
+ blockColor:(RCTUIColor *)blockColor;
128
+
129
+ /**
130
+ * Calculates the range for content rendered between start and current output length.
131
+ * Returns a range with length 0 if no content was rendered.
132
+ */
133
+ + (NSRange)rangeForRenderedContent:(NSMutableAttributedString *)output start:(NSUInteger)start;
134
+
135
+ /**
136
+ * Applies font and color attributes conditionally, only updating if they've changed.
137
+ * Returns YES if any attributes were updated, NO otherwise.
138
+ */
139
+ + (BOOL)applyFontAndColorAttributes:(NSMutableAttributedString *)output
140
+ range:(NSRange)range
141
+ font:(UIFont *)font
142
+ color:(RCTUIColor *)color
143
+ existingAttributes:(NSDictionary *)existingAttributes
144
+ shouldPreserveColors:(BOOL)shouldPreserveColors;
145
+ @end
@@ -0,0 +1,403 @@
1
+ #import "RenderContext.h"
2
+ #import "CodeBackground.h"
3
+ #import "FontUtils.h"
4
+ #import <React/RCTFont.h>
5
+
6
+ @implementation BlockStyle
7
+ @end
8
+
9
+ static NSArray<NSString *> *ENRMScopedKeyPaths(void)
10
+ {
11
+ static NSArray<NSString *> *keyPaths;
12
+ static dispatch_once_t onceToken;
13
+ dispatch_once(&onceToken, ^{
14
+ keyPaths = @[
15
+ @"currentBlockType",
16
+ @"currentHeadingLevel",
17
+ @"currentBlockStyle.fontSize",
18
+ @"currentBlockStyle.fontFamily",
19
+ @"currentBlockStyle.fontWeight",
20
+ @"currentBlockStyle.color",
21
+ @"currentBlockStyle.cachedFont",
22
+ @"currentBlockStyle.cachedTextAttributes",
23
+ @"blockquoteDepth",
24
+ @"listDepth",
25
+ @"listType",
26
+ @"listItemNumber",
27
+ @"listMarkerWidth",
28
+ @"listMarkerExtra",
29
+ @"ancestorMarkerOffset",
30
+ @"listItemMarkerExtra",
31
+ @"accumulatedIndent",
32
+ ];
33
+ });
34
+ return keyPaths;
35
+ }
36
+
37
+ @implementation RenderContext {
38
+ NSMutableDictionary<NSString *, UIFont *> *_fontCache;
39
+ NSParagraphStyle *_baseSpacerTemplate;
40
+ NSParagraphStyle *_baseBlockSpacerTemplate;
41
+ }
42
+
43
+ - (instancetype)init
44
+ {
45
+ if (self = [super init]) {
46
+ _linkRanges = [NSMutableArray array];
47
+ _linkURLs = [NSMutableArray array];
48
+ _headingRanges = [NSMutableArray array];
49
+ _headingLevels = [NSMutableArray array];
50
+ _imageRanges = [NSMutableArray array];
51
+ _imageAltTexts = [NSMutableArray array];
52
+ _imageURLs = [NSMutableArray array];
53
+ _listItemRanges = [NSMutableArray array];
54
+ _listItemPositions = [NSMutableArray array];
55
+ _listItemDepths = [NSMutableArray array];
56
+ _listItemOrdered = [NSMutableArray array];
57
+ _mathReporters = [NSMutableArray array];
58
+ _fontCache = [NSMutableDictionary dictionary];
59
+ _currentBlockStyle = [[BlockStyle alloc] init];
60
+ _allowFontScaling = YES;
61
+ _maxFontSizeMultiplier = 0;
62
+
63
+ NSMutableParagraphStyle *spacerTemplate = [[NSMutableParagraphStyle alloc] init];
64
+ _baseSpacerTemplate = [spacerTemplate copy];
65
+
66
+ NSMutableParagraphStyle *blockSpacerTemplate = [[NSMutableParagraphStyle alloc] init];
67
+ blockSpacerTemplate.minimumLineHeight = 1;
68
+ blockSpacerTemplate.maximumLineHeight = 1;
69
+ _baseBlockSpacerTemplate = [blockSpacerTemplate copy];
70
+
71
+ [self reset];
72
+ }
73
+ return self;
74
+ }
75
+
76
+ #pragma mark - Font Cache
77
+
78
+ - (UIFont *)cachedFontForSize:(CGFloat)fontSize family:(NSString *)fontFamily weight:(NSString *)fontWeight
79
+ {
80
+ CGFloat effectiveMultiplier = _allowFontScaling ? RCTFontSizeMultiplierWithMax(_maxFontSizeMultiplier) : 1.0;
81
+
82
+ NSString *weightKey = (fontWeight.length > 0) ? fontWeight : @"";
83
+ NSString *key =
84
+ [NSString stringWithFormat:@"%.1f|%@|%@|%.2f", fontSize, fontFamily ?: @"", weightKey, effectiveMultiplier];
85
+
86
+ UIFont *cached = _fontCache[key];
87
+ if (cached) {
88
+ return cached;
89
+ }
90
+
91
+ NSString *effectiveWeight = (fontWeight.length > 0) ? fontWeight : nil;
92
+
93
+ UIFont *font = [RCTFont updateFont:nil
94
+ withFamily:fontFamily
95
+ size:@(fontSize)
96
+ weight:effectiveWeight
97
+ style:nil
98
+ variant:nil
99
+ scaleMultiplier:effectiveMultiplier];
100
+
101
+ if (font) {
102
+ _fontCache[key] = font;
103
+ }
104
+ return font;
105
+ }
106
+
107
+ #pragma mark - Paragraph Style Factory
108
+
109
+ - (NSMutableParagraphStyle *)spacerStyleWithHeight:(CGFloat)height spacing:(CGFloat)spacing
110
+ {
111
+ NSMutableParagraphStyle *style = [_baseSpacerTemplate mutableCopy];
112
+ style.minimumLineHeight = height;
113
+ style.maximumLineHeight = height;
114
+ style.paragraphSpacing = spacing;
115
+ return style;
116
+ }
117
+
118
+ - (NSMutableParagraphStyle *)blockSpacerStyleWithMargin:(CGFloat)margin
119
+ {
120
+ NSMutableParagraphStyle *style = [_baseBlockSpacerTemplate mutableCopy];
121
+ style.paragraphSpacing = margin;
122
+ return style;
123
+ }
124
+
125
+ #pragma mark - Link Registry
126
+
127
+ - (void)registerLinkRange:(NSRange)range url:(NSString *)url
128
+ {
129
+ if (range.length == 0)
130
+ return;
131
+ [self.linkRanges addObject:[NSValue valueWithRange:range]];
132
+ [self.linkURLs addObject:url ?: @""];
133
+ }
134
+
135
+ - (void)applyLinkAttributesToString:(NSMutableAttributedString *)attributedString
136
+ {
137
+ NSUInteger length = attributedString.length;
138
+ for (NSUInteger i = 0; i < self.linkRanges.count; i++) {
139
+ NSRange range = [self.linkRanges[i] rangeValue];
140
+ if (NSMaxRange(range) > length)
141
+ continue;
142
+ [attributedString addAttribute:@"linkURL" value:self.linkURLs[i] range:range];
143
+ }
144
+ }
145
+
146
+ - (void)applyImageAttributesToString:(NSMutableAttributedString *)attributedString
147
+ {
148
+ NSUInteger length = attributedString.length;
149
+ for (NSUInteger i = 0; i < self.imageRanges.count; i++) {
150
+ NSRange range = [self.imageRanges[i] rangeValue];
151
+ if (NSMaxRange(range) > length)
152
+ continue;
153
+ [attributedString addAttribute:@"imageURL" value:self.imageURLs[i] range:range];
154
+ [attributedString addAttribute:@"imageAltText" value:self.imageAltTexts[i] range:range];
155
+ }
156
+ }
157
+
158
+ - (void)registerHeadingRange:(NSRange)range level:(NSInteger)level text:(NSString *)text
159
+ {
160
+ if (range.length == 0)
161
+ return;
162
+ [self.headingRanges addObject:[NSValue valueWithRange:range]];
163
+ [self.headingLevels addObject:@(level)];
164
+ }
165
+
166
+ - (void)registerImageRange:(NSRange)range altText:(NSString *)altText url:(NSString *)url
167
+ {
168
+ if (range.length == 0)
169
+ return;
170
+ [self.imageRanges addObject:[NSValue valueWithRange:range]];
171
+ [self.imageAltTexts addObject:altText ?: @""];
172
+ [self.imageURLs addObject:url ?: @""];
173
+ }
174
+
175
+ #pragma mark - Registration Helpers
176
+
177
+ - (void)registerListItemRange:(NSRange)range
178
+ position:(NSInteger)position
179
+ depth:(NSInteger)depth
180
+ isOrdered:(BOOL)isOrdered
181
+ {
182
+ if (![self isValidRange:range])
183
+ return;
184
+
185
+ [self.listItemRanges addObject:[NSValue valueWithRange:range]];
186
+ [self.listItemPositions addObject:@(position)];
187
+ [self.listItemDepths addObject:@(depth)];
188
+ [self.listItemOrdered addObject:@(isOrdered)];
189
+ }
190
+
191
+ #pragma mark - Private
192
+
193
+ - (BOOL)isValidRange:(NSRange)range
194
+ {
195
+ return range.length > 0 && range.location != NSNotFound;
196
+ }
197
+
198
+ #pragma mark - Block Style Management
199
+
200
+ /**
201
+ * Updates the shared BlockStyle object with new traits.
202
+ * This avoids allocating a new object for every block node in the AST.
203
+ */
204
+ - (void)setBlockStyle:(BlockType)type
205
+ fontSize:(CGFloat)fontSize
206
+ fontFamily:(NSString *)fontFamily
207
+ fontWeight:(NSString *)fontWeight
208
+ color:(RCTUIColor *)color
209
+ headingLevel:(NSInteger)headingLevel
210
+ {
211
+ _currentBlockType = type;
212
+ _currentHeadingLevel = headingLevel;
213
+
214
+ _currentBlockStyle.fontSize = fontSize;
215
+ _currentBlockStyle.fontFamily = fontFamily ?: @"";
216
+ _currentBlockStyle.fontWeight = fontWeight ?: @"normal";
217
+ _currentBlockStyle.color = color ?: [RCTUIColor blackColor];
218
+ }
219
+
220
+ - (void)setBlockStyle:(BlockType)type
221
+ fontSize:(CGFloat)fontSize
222
+ fontFamily:(NSString *)fontFamily
223
+ fontWeight:(NSString *)fontWeight
224
+ color:(RCTUIColor *)color
225
+ {
226
+ [self setBlockStyle:type fontSize:fontSize fontFamily:fontFamily fontWeight:fontWeight color:color headingLevel:0];
227
+ }
228
+
229
+ - (void)setBlockStyle:(BlockType)type font:(UIFont *)font color:(RCTUIColor *)color headingLevel:(NSInteger)headingLevel
230
+ {
231
+ _currentBlockType = type;
232
+ _currentHeadingLevel = headingLevel;
233
+
234
+ RCTUIColor *finalColor = color ?: [RCTUIColor blackColor];
235
+ _currentBlockStyle.cachedFont = font;
236
+ _currentBlockStyle.color = finalColor;
237
+
238
+ // Pre-create text attributes dictionary if we have both font and color
239
+ if (font) {
240
+ _currentBlockStyle.cachedTextAttributes =
241
+ @{NSFontAttributeName : font, NSForegroundColorAttributeName : finalColor};
242
+ }
243
+ }
244
+
245
+ - (BlockStyle *)getBlockStyle
246
+ {
247
+ return _currentBlockStyle;
248
+ }
249
+
250
+ - (NSDictionary *)getTextAttributes
251
+ {
252
+ BlockStyle *style = _currentBlockStyle;
253
+
254
+ // Return pre-cached attributes if available
255
+ if (style.cachedTextAttributes) {
256
+ return style.cachedTextAttributes;
257
+ }
258
+
259
+ // Fall back to creating attributes from font cache
260
+ UIFont *font = style.cachedFont;
261
+ if (!font) {
262
+ font = [self cachedFontForSize:style.fontSize family:style.fontFamily weight:style.fontWeight];
263
+ }
264
+ RCTUIColor *color = style.color ?: [RCTUIColor blackColor];
265
+
266
+ // Cache for future calls within same block
267
+ style.cachedTextAttributes = @{NSFontAttributeName : font, NSForegroundColorAttributeName : color};
268
+ return style.cachedTextAttributes;
269
+ }
270
+
271
+ - (void)clearBlockStyle
272
+ {
273
+ _currentBlockType = BlockTypeNone;
274
+ _currentHeadingLevel = 0;
275
+ _currentBlockStyle.cachedFont = nil;
276
+ _currentBlockStyle.cachedTextAttributes = nil;
277
+ }
278
+
279
+ - (id)snapshotScope
280
+ {
281
+ NSArray<NSString *> *keyPaths = ENRMScopedKeyPaths();
282
+ NSMutableDictionary *snapshot = [NSMutableDictionary dictionaryWithCapacity:keyPaths.count];
283
+ for (NSString *keyPath in keyPaths) {
284
+ snapshot[keyPath] = [self valueForKeyPath:keyPath] ?: [NSNull null];
285
+ }
286
+ return snapshot;
287
+ }
288
+
289
+ - (void)restoreScope:(id)snapshot
290
+ {
291
+ NSDictionary *frame = snapshot;
292
+ for (NSString *keyPath in ENRMScopedKeyPaths()) {
293
+ id value = frame[keyPath];
294
+ [self setValue:(value == [NSNull null] ? nil : value) forKeyPath:keyPath];
295
+ }
296
+ }
297
+
298
+ #pragma mark - Reset
299
+
300
+ - (void)reset
301
+ {
302
+ [_linkRanges removeAllObjects];
303
+ [_linkURLs removeAllObjects];
304
+ [_headingRanges removeAllObjects];
305
+ [_headingLevels removeAllObjects];
306
+ [_imageRanges removeAllObjects];
307
+ [_imageAltTexts removeAllObjects];
308
+ [_imageURLs removeAllObjects];
309
+ [_listItemRanges removeAllObjects];
310
+ [_listItemPositions removeAllObjects];
311
+ [_listItemDepths removeAllObjects];
312
+ [_listItemOrdered removeAllObjects];
313
+ [_mathReporters removeAllObjects];
314
+ [self clearBlockStyle];
315
+
316
+ _blockquoteDepth = 0;
317
+ _listDepth = 0;
318
+ _listType = ListTypeUnordered;
319
+ _listItemNumber = 0;
320
+ _listMarkerWidth = 0;
321
+ _listMarkerExtra = 0;
322
+ _ancestorMarkerOffset = 0;
323
+ _listItemMarkerExtra = 0;
324
+ _accumulatedIndent = 0;
325
+ _taskItemCount = 0;
326
+
327
+ // Revert shared style object to baseline defaults
328
+ _currentBlockStyle.fontSize = 0;
329
+ _currentBlockStyle.fontFamily = @"";
330
+ _currentBlockStyle.fontWeight = @"";
331
+ _currentBlockStyle.color = [RCTUIColor blackColor];
332
+ }
333
+
334
+ #pragma mark - Static Utilities
335
+
336
+ /**
337
+ * Determines if specific inline attributes should protect the current color.
338
+ */
339
+ + (BOOL)shouldPreserveColors:(NSDictionary *)attrs
340
+ {
341
+ return (attrs[NSLinkAttributeName] != nil || attrs[CodeAttributeName] != nil);
342
+ }
343
+
344
+ // TODO: Unify calculateStrongColor and calculateHighlightColor into a single helper that
345
+ // resolves inline foreground color from (configColor, inheritanceBaseline, blockColor).
346
+
347
+ /**
348
+ * Calculates whether a strong color should override the block color.
349
+ */
350
+ + (RCTUIColor *)calculateStrongColor:(RCTUIColor *)configStrongColor blockColor:(RCTUIColor *)blockColor
351
+ {
352
+ if (!configStrongColor || [configStrongColor isEqual:blockColor]) {
353
+ return blockColor;
354
+ }
355
+ return configStrongColor;
356
+ }
357
+
358
+ + (RCTUIColor *)calculateHighlightColor:(RCTUIColor *)configHighlightColor
359
+ paragraphColor:(RCTUIColor *)paragraphColor
360
+ blockColor:(RCTUIColor *)blockColor
361
+ {
362
+ if ([configHighlightColor isEqual:paragraphColor]) {
363
+ return blockColor;
364
+ }
365
+ return configHighlightColor;
366
+ }
367
+
368
+ /**
369
+ * Safely calculates a range based on a start point and the current output length.
370
+ */
371
+ + (NSRange)rangeForRenderedContent:(NSMutableAttributedString *)output start:(NSUInteger)start
372
+ {
373
+ if (output.length < start)
374
+ return NSMakeRange(start, 0);
375
+ return NSMakeRange(start, output.length - start);
376
+ }
377
+
378
+ /**
379
+ * Surgically applies attributes only if they differ from current values.
380
+ * This minimizes "dirtying" the AttributedString, which improves layout performance.
381
+ */
382
+ + (void)applyFontAndColorAttributes:(NSMutableAttributedString *)output
383
+ range:(NSRange)range
384
+ font:(UIFont *)font
385
+ color:(RCTUIColor *)color
386
+ existingAttributes:(NSDictionary *)attrs
387
+ shouldPreserveColors:(BOOL)shouldPreserve
388
+ {
389
+ if (range.length == 0)
390
+ return;
391
+
392
+ // Font Update: Only if it exists and is different
393
+ if (font && ![font isEqual:attrs[NSFontAttributeName]]) {
394
+ [output addAttribute:NSFontAttributeName value:font range:range];
395
+ }
396
+
397
+ // Color Update: Only if not a link/code and different from existing
398
+ if (color && !shouldPreserve && ![color isEqual:attrs[NSForegroundColorAttributeName]]) {
399
+ [output addAttribute:NSForegroundColorAttributeName value:color range:range];
400
+ }
401
+ }
402
+
403
+ @end
@@ -0,0 +1,12 @@
1
+ #import "TiptapASTNode.h"
2
+ #import "NodeRenderer.h"
3
+
4
+ @class RenderContext;
5
+
6
+ @interface RendererFactory : NSObject
7
+ - (instancetype)initWithConfig:(id)config;
8
+ - (id<NodeRenderer>)rendererForNodeType:(TiptapNodeType)type;
9
+ - (void)renderChildrenOfNode:(TiptapASTNode *)node
10
+ into:(NSMutableAttributedString *)output
11
+ context:(RenderContext *)context;
12
+ @end