@mathers101/react-native-render-rich-text 0.1.9 → 0.1.14

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 (327) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +140 -140
  3. package/ReactNativeRenderRichText.podspec +23 -23
  4. package/android/build.gradle +86 -86
  5. package/android/consumer-rules.pro +3 -3
  6. package/android/src/main/AndroidManifest.xml +2 -2
  7. package/android/src/main/java/com/renderrichtext/EnrichedTiptapTextLayoutManager.kt +24 -24
  8. package/android/src/main/java/com/renderrichtext/EnrichedTiptapTextPackage.kt +13 -13
  9. package/android/src/main/java/com/renderrichtext/MeasurementStore.kt +644 -644
  10. package/android/src/main/java/com/renderrichtext/accessibility/AccessibilityLabels.kt +17 -17
  11. package/android/src/main/java/com/renderrichtext/accessibility/AccessibleTiptapTextView.kt +112 -112
  12. package/android/src/main/java/com/renderrichtext/accessibility/TiptapAccessibilityHelper.kt +576 -576
  13. package/android/src/main/java/com/renderrichtext/events/CodeBlockPressEvent.kt +24 -24
  14. package/android/src/main/java/com/renderrichtext/events/ContextMenuItemPressEvent.kt +28 -28
  15. package/android/src/main/java/com/renderrichtext/events/CopyPressEvent.kt +24 -24
  16. package/android/src/main/java/com/renderrichtext/events/ImagePressEvent.kt +25 -25
  17. package/android/src/main/java/com/renderrichtext/events/LatexErrorEvent.kt +29 -29
  18. package/android/src/main/java/com/renderrichtext/events/LinkLongPressEvent.kt +23 -23
  19. package/android/src/main/java/com/renderrichtext/events/LinkPressEvent.kt +23 -23
  20. package/android/src/main/java/com/renderrichtext/events/MentionLongPressEvent.kt +25 -25
  21. package/android/src/main/java/com/renderrichtext/events/MentionPressEvent.kt +25 -25
  22. package/android/src/main/java/com/renderrichtext/events/TaskListItemPressEvent.kt +26 -26
  23. package/android/src/main/java/com/renderrichtext/math/LatexErrorReporter.kt +9 -9
  24. package/android/src/main/java/com/renderrichtext/parser/Parser.kt +59 -59
  25. package/android/src/main/java/com/renderrichtext/parser/TextLinkMatching.kt +35 -35
  26. package/android/src/main/java/com/renderrichtext/renderer/BaselineShiftRenderer.kt +45 -45
  27. package/android/src/main/java/com/renderrichtext/renderer/BlankLineRenderer.kt +39 -39
  28. package/android/src/main/java/com/renderrichtext/renderer/BlockquoteRenderer.kt +243 -243
  29. package/android/src/main/java/com/renderrichtext/renderer/BlockquoteTextRenderer.kt +56 -56
  30. package/android/src/main/java/com/renderrichtext/renderer/CodeBlockRenderer.kt +135 -135
  31. package/android/src/main/java/com/renderrichtext/renderer/CodeRenderer.kt +37 -37
  32. package/android/src/main/java/com/renderrichtext/renderer/EmphasisRenderer.kt +28 -28
  33. package/android/src/main/java/com/renderrichtext/renderer/HeadingRenderer.kt +81 -81
  34. package/android/src/main/java/com/renderrichtext/renderer/HighlightRenderer.kt +26 -26
  35. package/android/src/main/java/com/renderrichtext/renderer/LineBreakRenderer.kt +17 -17
  36. package/android/src/main/java/com/renderrichtext/renderer/LinkRenderer.kt +90 -90
  37. package/android/src/main/java/com/renderrichtext/renderer/ListContextManager.kt +109 -109
  38. package/android/src/main/java/com/renderrichtext/renderer/ListItemRenderer.kt +211 -211
  39. package/android/src/main/java/com/renderrichtext/renderer/ListRenderer.kt +133 -133
  40. package/android/src/main/java/com/renderrichtext/renderer/MentionRenderer.kt +85 -85
  41. package/android/src/main/java/com/renderrichtext/renderer/ParagraphRenderer.kt +91 -91
  42. package/android/src/main/java/com/renderrichtext/renderer/Renderer.kt +148 -148
  43. package/android/src/main/java/com/renderrichtext/renderer/SoftBreakRenderer.kt +17 -17
  44. package/android/src/main/java/com/renderrichtext/renderer/SpanStyleCache.kt +143 -143
  45. package/android/src/main/java/com/renderrichtext/renderer/StrikethroughRenderer.kt +28 -28
  46. package/android/src/main/java/com/renderrichtext/renderer/StrongRenderer.kt +28 -28
  47. package/android/src/main/java/com/renderrichtext/renderer/TextRenderer.kt +31 -31
  48. package/android/src/main/java/com/renderrichtext/renderer/ThematicBreakRenderer.kt +46 -46
  49. package/android/src/main/java/com/renderrichtext/renderer/UnderlineRenderer.kt +28 -28
  50. package/android/src/main/java/com/renderrichtext/spans/BaseListSpan.kt +164 -164
  51. package/android/src/main/java/com/renderrichtext/spans/BaselineShiftSpan.kt +27 -27
  52. package/android/src/main/java/com/renderrichtext/spans/BlockquoteSpan.kt +302 -302
  53. package/android/src/main/java/com/renderrichtext/spans/CodeBackgroundSpan.kt +205 -205
  54. package/android/src/main/java/com/renderrichtext/spans/CodeBlockSpan.kt +216 -216
  55. package/android/src/main/java/com/renderrichtext/spans/CodeSpan.kt +32 -32
  56. package/android/src/main/java/com/renderrichtext/spans/EmphasisSpan.kt +42 -42
  57. package/android/src/main/java/com/renderrichtext/spans/FadeInSpan.kt +29 -29
  58. package/android/src/main/java/com/renderrichtext/spans/HeadingSpan.kt +38 -38
  59. package/android/src/main/java/com/renderrichtext/spans/HighlightSpan.kt +80 -80
  60. package/android/src/main/java/com/renderrichtext/spans/ImageSpan.kt +481 -481
  61. package/android/src/main/java/com/renderrichtext/spans/InlineBackgroundGeometry.kt +42 -42
  62. package/android/src/main/java/com/renderrichtext/spans/LineHeightSpan.kt +39 -39
  63. package/android/src/main/java/com/renderrichtext/spans/LinkPillIconCache.kt +154 -154
  64. package/android/src/main/java/com/renderrichtext/spans/LinkPillSpan.kt +381 -381
  65. package/android/src/main/java/com/renderrichtext/spans/LinkSpan.kt +68 -68
  66. package/android/src/main/java/com/renderrichtext/spans/ListItemSpacingSpan.kt +33 -33
  67. package/android/src/main/java/com/renderrichtext/spans/ListMarkerAnchorSpan.kt +38 -38
  68. package/android/src/main/java/com/renderrichtext/spans/MarginBottomSpan.kt +76 -76
  69. package/android/src/main/java/com/renderrichtext/spans/MentionChipSpan.kt +132 -132
  70. package/android/src/main/java/com/renderrichtext/spans/MentionSpan.kt +46 -46
  71. package/android/src/main/java/com/renderrichtext/spans/OrderedListSpan.kt +127 -127
  72. package/android/src/main/java/com/renderrichtext/spans/SpoilerSpan.kt +33 -33
  73. package/android/src/main/java/com/renderrichtext/spans/StrikethroughSpan.kt +12 -12
  74. package/android/src/main/java/com/renderrichtext/spans/StrongSpan.kt +39 -39
  75. package/android/src/main/java/com/renderrichtext/spans/TaskListSpan.kt +143 -143
  76. package/android/src/main/java/com/renderrichtext/spans/TextSpan.kt +26 -26
  77. package/android/src/main/java/com/renderrichtext/spans/ThematicBreakSpan.kt +69 -69
  78. package/android/src/main/java/com/renderrichtext/spans/UnorderedListSpan.kt +96 -96
  79. package/android/src/main/java/com/renderrichtext/spoiler/SpoilerStubs.kt +46 -46
  80. package/android/src/main/java/com/renderrichtext/styles/BaseBlockStyle.kt +11 -11
  81. package/android/src/main/java/com/renderrichtext/styles/BlockquoteStyle.kt +83 -83
  82. package/android/src/main/java/com/renderrichtext/styles/CodeBlockStyle.kt +80 -80
  83. package/android/src/main/java/com/renderrichtext/styles/CodeStyle.kt +26 -26
  84. package/android/src/main/java/com/renderrichtext/styles/EmphasisStyle.kt +21 -21
  85. package/android/src/main/java/com/renderrichtext/styles/FactoidStyle.kt +21 -21
  86. package/android/src/main/java/com/renderrichtext/styles/HeadingStyle.kt +33 -33
  87. package/android/src/main/java/com/renderrichtext/styles/HighlightStyle.kt +19 -19
  88. package/android/src/main/java/com/renderrichtext/styles/ImageStyle.kt +29 -29
  89. package/android/src/main/java/com/renderrichtext/styles/InlineImageStyle.kt +17 -17
  90. package/android/src/main/java/com/renderrichtext/styles/InlineMathStyle.kt +17 -17
  91. package/android/src/main/java/com/renderrichtext/styles/LinkPillContent.kt +36 -36
  92. package/android/src/main/java/com/renderrichtext/styles/LinkPillStyle.kt +44 -44
  93. package/android/src/main/java/com/renderrichtext/styles/LinkStyle.kt +23 -23
  94. package/android/src/main/java/com/renderrichtext/styles/LinkVariantEntry.kt +34 -34
  95. package/android/src/main/java/com/renderrichtext/styles/ListStyle.kt +65 -65
  96. package/android/src/main/java/com/renderrichtext/styles/MathStyle.kt +29 -29
  97. package/android/src/main/java/com/renderrichtext/styles/MentionStyle.kt +19 -19
  98. package/android/src/main/java/com/renderrichtext/styles/ParagraphStyle.kt +33 -33
  99. package/android/src/main/java/com/renderrichtext/styles/SpoilerStyle.kt +27 -27
  100. package/android/src/main/java/com/renderrichtext/styles/StrikethroughStyle.kt +17 -17
  101. package/android/src/main/java/com/renderrichtext/styles/StrongStyle.kt +21 -21
  102. package/android/src/main/java/com/renderrichtext/styles/StyleConfig.kt +411 -411
  103. package/android/src/main/java/com/renderrichtext/styles/StyleParser.kt +92 -92
  104. package/android/src/main/java/com/renderrichtext/styles/SubscriptStyle.kt +16 -16
  105. package/android/src/main/java/com/renderrichtext/styles/SuperscriptStyle.kt +16 -16
  106. package/android/src/main/java/com/renderrichtext/styles/TableStyle.kt +75 -75
  107. package/android/src/main/java/com/renderrichtext/styles/TaskListStyle.kt +29 -29
  108. package/android/src/main/java/com/renderrichtext/styles/TextAlignment.kt +32 -32
  109. package/android/src/main/java/com/renderrichtext/styles/ThematicBreakStyle.kt +23 -23
  110. package/android/src/main/java/com/renderrichtext/styles/UnderlineStyle.kt +17 -17
  111. package/android/src/main/java/com/renderrichtext/styles/VideoStyle.kt +31 -31
  112. package/android/src/main/java/com/renderrichtext/utils/common/BorderStyleUtils.kt +86 -86
  113. package/android/src/main/java/com/renderrichtext/utils/common/BreakStrategyUtils.kt +32 -32
  114. package/android/src/main/java/com/renderrichtext/utils/common/CodeBlockHighlighter.kt +36 -36
  115. package/android/src/main/java/com/renderrichtext/utils/common/CodeBlockNode.kt +42 -42
  116. package/android/src/main/java/com/renderrichtext/utils/common/EllipsizeUtils.kt +27 -27
  117. package/android/src/main/java/com/renderrichtext/utils/common/EnrichedTiptapAncestorUtils.kt +10 -10
  118. package/android/src/main/java/com/renderrichtext/utils/common/FeatureFlags.kt +9 -9
  119. package/android/src/main/java/com/renderrichtext/utils/common/LinkRecognitionProps.kt +31 -31
  120. package/android/src/main/java/com/renderrichtext/utils/common/LinkRegexConfig.kt +56 -56
  121. package/android/src/main/java/com/renderrichtext/utils/common/MotionPreferences.kt +18 -18
  122. package/android/src/main/java/com/renderrichtext/utils/common/ReadableMapExtensions.kt +28 -28
  123. package/android/src/main/java/com/renderrichtext/utils/common/layout/RTLUtils.kt +6 -6
  124. package/android/src/main/java/com/renderrichtext/utils/common/serialization/TiptapASTSerializer.kt +368 -368
  125. package/android/src/main/java/com/renderrichtext/utils/text/ImageCache.kt +88 -88
  126. package/android/src/main/java/com/renderrichtext/utils/text/ImageDownloader.kt +203 -203
  127. package/android/src/main/java/com/renderrichtext/utils/text/LocalImageLoader.kt +167 -167
  128. package/android/src/main/java/com/renderrichtext/utils/text/TailFadeInAnimator.kt +84 -84
  129. package/android/src/main/java/com/renderrichtext/utils/text/conversion/HTMLGenerator.kt +1105 -1105
  130. package/android/src/main/java/com/renderrichtext/utils/text/conversion/TiptapExtractor.kt +423 -423
  131. package/android/src/main/java/com/renderrichtext/utils/text/extensions/ParagraphUtils.kt +9 -9
  132. package/android/src/main/java/com/renderrichtext/utils/text/extensions/SpannableExtensions.kt +9 -9
  133. package/android/src/main/java/com/renderrichtext/utils/text/extensions/TextPaintExtensions.kt +76 -76
  134. package/android/src/main/java/com/renderrichtext/utils/text/interaction/CheckboxTouchHelper.kt +61 -61
  135. package/android/src/main/java/com/renderrichtext/utils/text/interaction/TaskListTapUtils.kt +286 -286
  136. package/android/src/main/java/com/renderrichtext/utils/text/span/ApplyLineHeight.kt +39 -39
  137. package/android/src/main/java/com/renderrichtext/utils/text/span/BlockSpacing.kt +142 -142
  138. package/android/src/main/java/com/renderrichtext/utils/text/span/SpanFlags.kt +43 -43
  139. package/android/src/main/java/com/renderrichtext/utils/text/span/WidthAwareSpans.kt +30 -30
  140. package/android/src/main/java/com/renderrichtext/utils/text/view/CodeBlockPressHost.kt +15 -15
  141. package/android/src/main/java/com/renderrichtext/utils/text/view/ImagePressHost.kt +19 -19
  142. package/android/src/main/java/com/renderrichtext/utils/text/view/SelectionActionMode.kt +235 -235
  143. package/android/src/main/java/com/renderrichtext/utils/text/view/TextSelectionColors.kt +48 -48
  144. package/android/src/main/java/com/renderrichtext/utils/text/view/TextViewSetup.kt +119 -119
  145. package/android/src/main/java/com/renderrichtext/views/ContextMenuPopup.kt +217 -217
  146. package/android/src/main/java/com/renderrichtext/views/CopyGlyph.kt +101 -101
  147. package/android/src/main/java/com/renderrichtext/views/WrapGlyph.kt +40 -40
  148. package/android/src/main/jni/CMakeLists.txt +52 -52
  149. package/android/src/main/jni/react/renderer/components/RichTextSpec/ComponentDescriptors.h +30 -30
  150. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextComponentDescriptor.h +29 -29
  151. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextMeasurementManager.cpp +45 -45
  152. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextMeasurementManager.h +21 -21
  153. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextShadowNode.cpp +38 -38
  154. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextShadowNode.h +53 -53
  155. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextState.cpp +9 -9
  156. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextState.h +24 -24
  157. package/android/src/main/jni/react/renderer/components/RichTextSpec/conversions.h +40 -40
  158. package/cpp/parser/TiptapParser.hpp +13 -13
  159. package/cpp/vendor/nlohmann/json.hpp +24765 -24765
  160. package/ios/EnrichedTiptapText.h +27 -27
  161. package/ios/attachments/ENRMImageAttachment.h +51 -51
  162. package/ios/attachments/ENRMImageAttachment.m +398 -398
  163. package/ios/attachments/ENRMLinkPillAttachment.h +47 -47
  164. package/ios/attachments/ENRMLinkPillAttachment.m +324 -324
  165. package/ios/attachments/ENRMLinkPillIconCache.h +28 -28
  166. package/ios/attachments/ENRMLinkPillIconCache.m +181 -181
  167. package/ios/attachments/ENRMLinkPillText.h +27 -27
  168. package/ios/attachments/ENRMLinkPillText.m +118 -118
  169. package/ios/attachments/ENRMMathInlineAttachment.h +7 -7
  170. package/ios/attachments/ENRMMathInlineAttachment.m +4 -4
  171. package/ios/attachments/ThematicBreakAttachment.h +15 -15
  172. package/ios/attachments/ThematicBreakAttachment.m +33 -33
  173. package/ios/internals/ENRMViewFreeMeasurement.h +208 -208
  174. package/ios/internals/EnrichedTiptapTextComponentDescriptor.h +19 -19
  175. package/ios/internals/EnrichedTiptapTextShadowNode.h +43 -43
  176. package/ios/internals/EnrichedTiptapTextShadowNode.mm +69 -69
  177. package/ios/internals/EnrichedTiptapTextState.h +24 -24
  178. package/ios/internals/MeasurementCache.h +308 -308
  179. package/ios/internals/ShadowMeasurementUtils.h +145 -145
  180. package/ios/parser/ENRMTextLinkAttributes.h +7 -7
  181. package/ios/parser/ENRMTiptapParser.h +33 -33
  182. package/ios/parser/ENRMTiptapParser.mm +73 -73
  183. package/ios/parser/TiptapASTNode.m +52 -52
  184. package/ios/renderer/AttributedRenderer.h +23 -23
  185. package/ios/renderer/AttributedRenderer.m +229 -229
  186. package/ios/renderer/BaseRenderer.h +33 -33
  187. package/ios/renderer/BaseRenderer.m +46 -46
  188. package/ios/renderer/BaselineShiftTextAttributes.h +10 -10
  189. package/ios/renderer/BaselineShiftTextAttributes.m +26 -26
  190. package/ios/renderer/BlankLineRenderer.h +4 -4
  191. package/ios/renderer/BlankLineRenderer.m +51 -51
  192. package/ios/renderer/BlockquoteRenderer.h +6 -6
  193. package/ios/renderer/BlockquoteRenderer.m +258 -258
  194. package/ios/renderer/CodeBlockRenderer.h +9 -9
  195. package/ios/renderer/CodeBlockRenderer.m +99 -99
  196. package/ios/renderer/CodeRenderer.h +9 -9
  197. package/ios/renderer/CodeRenderer.m +69 -69
  198. package/ios/renderer/ENRMBlockquoteTextRenderer.h +25 -25
  199. package/ios/renderer/ENRMBlockquoteTextRenderer.m +48 -48
  200. package/ios/renderer/EmphasisRenderer.h +5 -5
  201. package/ios/renderer/EmphasisRenderer.m +99 -99
  202. package/ios/renderer/HeadingRenderer.h +6 -6
  203. package/ios/renderer/HeadingRenderer.m +102 -102
  204. package/ios/renderer/HighlightRenderer.h +7 -7
  205. package/ios/renderer/HighlightRenderer.m +33 -33
  206. package/ios/renderer/LinkRenderer.h +6 -6
  207. package/ios/renderer/LinkRenderer.m +157 -157
  208. package/ios/renderer/ListItemRenderer.h +24 -24
  209. package/ios/renderer/ListItemRenderer.m +283 -283
  210. package/ios/renderer/ListRenderer.h +13 -13
  211. package/ios/renderer/ListRenderer.m +126 -126
  212. package/ios/renderer/MentionRenderer.h +9 -9
  213. package/ios/renderer/MentionRenderer.m +96 -96
  214. package/ios/renderer/NodeRenderer.h +8 -8
  215. package/ios/renderer/ParagraphRenderer.h +6 -6
  216. package/ios/renderer/ParagraphRenderer.m +85 -85
  217. package/ios/renderer/RenderContext.h +145 -145
  218. package/ios/renderer/RenderContext.m +402 -402
  219. package/ios/renderer/RendererFactory.h +12 -12
  220. package/ios/renderer/StrikethroughRenderer.h +5 -5
  221. package/ios/renderer/StrikethroughRenderer.m +30 -30
  222. package/ios/renderer/StrongRenderer.h +5 -5
  223. package/ios/renderer/StrongRenderer.m +87 -87
  224. package/ios/renderer/TextRenderer.h +6 -6
  225. package/ios/renderer/TextRenderer.m +18 -18
  226. package/ios/renderer/ThematicBreakRenderer.h +4 -4
  227. package/ios/renderer/ThematicBreakRenderer.m +41 -41
  228. package/ios/renderer/UnderlineRenderer.h +4 -4
  229. package/ios/renderer/UnderlineRenderer.m +41 -41
  230. package/ios/styles/ENRMFontSlot.h +12 -12
  231. package/ios/styles/ENRMFontSlot.m +24 -24
  232. package/ios/styles/StyleConfig.h +488 -488
  233. package/ios/styles/StyleConfig.mm +2820 -2820
  234. package/ios/utils/AccessibilityInfo.h +35 -35
  235. package/ios/utils/AccessibilityInfo.m +24 -24
  236. package/ios/utils/BlockquoteBorder.h +26 -26
  237. package/ios/utils/BlockquoteBorder.m +294 -294
  238. package/ios/utils/CodeBackground.h +19 -19
  239. package/ios/utils/CodeBackground.m +196 -196
  240. package/ios/utils/CodeBlockBackground.h +17 -17
  241. package/ios/utils/CodeBlockBackground.m +102 -102
  242. package/ios/utils/ContextMenuUtils.h +76 -76
  243. package/ios/utils/ContextMenuUtils.mm +75 -75
  244. package/ios/utils/ENRMAccessibilityLabels.h +40 -40
  245. package/ios/utils/ENRMAccessibilityLabels.m +5 -5
  246. package/ios/utils/ENRMAsyncRenderCoordinator.h +24 -24
  247. package/ios/utils/ENRMAsyncRenderCoordinator.m +37 -37
  248. package/ios/utils/ENRMAtomicSize.h +65 -65
  249. package/ios/utils/ENRMCodeBlockContent.h +37 -37
  250. package/ios/utils/ENRMCodeBlockContent.mm +89 -89
  251. package/ios/utils/ENRMFeatureFlags.h +25 -25
  252. package/ios/utils/ENRMImageDownloader.h +30 -30
  253. package/ios/utils/ENRMImageDownloader.m +168 -168
  254. package/ios/utils/ENRMLatexErrorCoordinator.h +27 -27
  255. package/ios/utils/ENRMLatexErrorCoordinator.mm +75 -75
  256. package/ios/utils/ENRMLatexErrorReporting.h +13 -13
  257. package/ios/utils/ENRMLinkContextMenus.h +93 -93
  258. package/ios/utils/ENRMLinkContextMenus.m +178 -178
  259. package/ios/utils/ENRMLinkRegexConfig.h +30 -30
  260. package/ios/utils/ENRMLinkRegexConfig.mm +104 -104
  261. package/ios/utils/ENRMLinkRegexProps.h +23 -23
  262. package/ios/utils/ENRMLocalImageLoader.h +35 -35
  263. package/ios/utils/ENRMLocalImageLoader.m +111 -111
  264. package/ios/utils/ENRMMenuAction.h +27 -27
  265. package/ios/utils/ENRMMenuAction.m +33 -33
  266. package/ios/utils/ENRMSpoilerOverlayManager.h +15 -15
  267. package/ios/utils/ENRMSpoilerOverlayManager.m +19 -19
  268. package/ios/utils/ENRMSpoilerTapUtils.h +6 -6
  269. package/ios/utils/ENRMSpoilerTapUtils.m +11 -11
  270. package/ios/utils/ENRMTailFadeInAnimator.h +16 -16
  271. package/ios/utils/ENRMTailFadeInAnimator.m +161 -161
  272. package/ios/utils/ENRMTextHitTest.h +23 -23
  273. package/ios/utils/ENRMTextHitTest.m +20 -20
  274. package/ios/utils/ENRMTextInteractionUtils.h +20 -20
  275. package/ios/utils/ENRMTextInteractionUtils.m +15 -15
  276. package/ios/utils/ENRMTextRenderer.h +38 -38
  277. package/ios/utils/ENRMTextRenderer.m +54 -54
  278. package/ios/utils/ENRMTextViewSetup.h +132 -132
  279. package/ios/utils/ENRMUIKit.h +429 -429
  280. package/ios/utils/EditMenuUtils.h +105 -105
  281. package/ios/utils/EditMenuUtils.m +143 -143
  282. package/ios/utils/FontScaleObserver.h +10 -10
  283. package/ios/utils/FontScaleObserver.m +55 -55
  284. package/ios/utils/FontUtils.h +31 -31
  285. package/ios/utils/FontUtils.m +63 -63
  286. package/ios/utils/HTMLGenerator.h +25 -25
  287. package/ios/utils/HTMLGenerator.m +1041 -1041
  288. package/ios/utils/HeightUpdateUtils.h +25 -25
  289. package/ios/utils/ImageRequestHeaderUtils.h +35 -35
  290. package/ios/utils/LastElementUtils.h +97 -97
  291. package/ios/utils/LinkContextMenuUtils.h +55 -55
  292. package/ios/utils/LinkPillContentUtils.h +46 -46
  293. package/ios/utils/ListMarkerDrawer.h +15 -15
  294. package/ios/utils/ListMarkerDrawer.m +239 -239
  295. package/ios/utils/MentionBackground.h +26 -26
  296. package/ios/utils/MentionBackground.m +86 -86
  297. package/ios/utils/ParagraphStyleUtils.h +87 -87
  298. package/ios/utils/ParagraphStyleUtils.m +484 -484
  299. package/ios/utils/PasteboardUtils.h +48 -48
  300. package/ios/utils/PasteboardUtils.m +166 -166
  301. package/ios/utils/RTFExportUtils.h +24 -24
  302. package/ios/utils/RTFExportUtils.m +299 -299
  303. package/ios/utils/SelectionColorUtils.h +14 -14
  304. package/ios/utils/StylePropsUtils.h +1340 -1340
  305. package/ios/utils/TaskListTapUtils.h +6 -6
  306. package/ios/utils/TaskListTapUtils.m +14 -14
  307. package/ios/utils/TextViewLayoutManager.h +14 -14
  308. package/ios/utils/TiptapAccessibilityElementBuilder.h +43 -43
  309. package/ios/utils/TiptapAccessibilityElementBuilder.m +432 -432
  310. package/ios/utils/TiptapExtractor.h +17 -17
  311. package/ios/utils/TiptapExtractor.m +367 -367
  312. package/ios/views/ENRMTiptapTextView.h +25 -25
  313. package/ios/views/ENRMTiptapTextView.m +247 -247
  314. package/package.json +65 -70
  315. package/react-native.config.js +10 -10
  316. package/src/admonitionDefaults.ts +58 -58
  317. package/src/darkModeTextStyle.ts +99 -99
  318. package/src/headingDefaults.ts +21 -21
  319. package/src/index.tsx +4 -4
  320. package/src/linkVariantUtils.ts +120 -120
  321. package/src/normalizeTiptapStyle.ts +397 -397
  322. package/src/rn-globals.d.ts +1 -1
  323. package/src/styleUtils.ts +107 -107
  324. package/src/types/TiptapStyle.ts +532 -532
  325. package/src/types/TiptapStyleInternal.ts +299 -299
  326. package/src/types/linkPill.ts +9 -9
  327. package/src/utils/isDev.ts +4 -4
@@ -1,23 +1,23 @@
1
- #import <Foundation/Foundation.h>
2
-
3
- @class ENRMBlockquoteTextRenderer;
4
- @class TiptapASTNode;
5
- @class RenderContext;
6
-
7
- NS_ASSUME_NONNULL_BEGIN
8
-
9
- @interface AttributedRenderer : NSObject
10
- - (instancetype)initWithConfig:(id)config;
11
- // Renders a flat list of sibling nodes into an attributed string: sets the baseline block style,
12
- // walks each node, and trims the trailing block margin. Pass a non-nil block to render the nodes as
13
- // a blockquote's own content (blockquote baseline + the quote's line height applied over the run);
14
- // it draws no box - the ENRMBlockquoteContainerView draws the border/background/padding. See
15
- // ENRMBlockquoteTextRenderer.
16
- - (NSMutableAttributedString *)renderNodes:(NSArray<TiptapASTNode *> *)nodes
17
- context:(RenderContext *)context
18
- block:(nullable ENRMBlockquoteTextRenderer *)block;
19
- - (CGFloat)getLastElementMarginBottom;
20
- - (void)setAllowTrailingMargin:(BOOL)allow;
21
- @end
22
-
23
- NS_ASSUME_NONNULL_END
1
+ #import <Foundation/Foundation.h>
2
+
3
+ @class ENRMBlockquoteTextRenderer;
4
+ @class TiptapASTNode;
5
+ @class RenderContext;
6
+
7
+ NS_ASSUME_NONNULL_BEGIN
8
+
9
+ @interface AttributedRenderer : NSObject
10
+ - (instancetype)initWithConfig:(id)config;
11
+ // Renders a flat list of sibling nodes into an attributed string: sets the baseline block style,
12
+ // walks each node, and trims the trailing block margin. Pass a non-nil block to render the nodes as
13
+ // a blockquote's own content (blockquote baseline + the quote's line height applied over the run);
14
+ // it draws no box - the ENRMBlockquoteContainerView draws the border/background/padding. See
15
+ // ENRMBlockquoteTextRenderer.
16
+ - (NSMutableAttributedString *)renderNodes:(NSArray<TiptapASTNode *> *)nodes
17
+ context:(RenderContext *)context
18
+ block:(nullable ENRMBlockquoteTextRenderer *)block;
19
+ - (CGFloat)getLastElementMarginBottom;
20
+ - (void)setAllowTrailingMargin:(BOOL)allow;
21
+ @end
22
+
23
+ NS_ASSUME_NONNULL_END
@@ -1,229 +1,229 @@
1
- #import "AttributedRenderer.h"
2
- #import "BlockquoteBorder.h"
3
- #import "CodeBlockBackground.h"
4
- #import "ENRMBlockquoteTextRenderer.h"
5
- #import "ENRMLinkPillText.h"
6
- #import "LastElementUtils.h"
7
- #import "TiptapASTNode.h"
8
- #import "NodeRenderer.h"
9
- #import "ParagraphStyleUtils.h"
10
- #import "RenderContext.h"
11
- #import "RendererFactory.h"
12
- #import "StyleConfig.h"
13
-
14
- @implementation AttributedRenderer {
15
- StyleConfig *_config;
16
- RendererFactory *_rendererFactory;
17
- CGFloat _lastElementMarginBottom;
18
- BOOL _allowTrailingMargin;
19
- }
20
-
21
- - (instancetype)initWithConfig:(StyleConfig *)config
22
- {
23
- self = [super init];
24
- if (self) {
25
- _config = config;
26
- _rendererFactory = [[RendererFactory alloc] initWithConfig:config];
27
- _lastElementMarginBottom = 0.0;
28
- _allowTrailingMargin = NO;
29
- }
30
- return self;
31
- }
32
-
33
- /**
34
- * Entry point for rendering a flat list of sibling nodes (e.g. a document's or a block segment's
35
- * children). Sets the baseline block style, runs the recursive traversal, and trims the trailing
36
- * block margin. An optional [block] decorates the pass - it enters a block baseline before the nodes
37
- * render and post-processes the finished string - letting a caller render content as e.g. blockquote
38
- * text without this class knowing anything block-specific. See ENRMBlockquoteTextRenderer.
39
- */
40
- - (NSMutableAttributedString *)renderNodes:(NSArray<TiptapASTNode *> *)nodes
41
- context:(RenderContext *)context
42
- block:(ENRMBlockquoteTextRenderer *)block
43
- {
44
- // 1. Establish the baseline block style. This ensures leaf nodes (like Text) have valid
45
- // attributes if they appear at the top level. A decorator overrides the default paragraph
46
- // baseline (e.g. the blockquote baseline so paragraphs render tight and pick up the quote's
47
- // font/color).
48
- if (block) {
49
- [block pushOnContext:context];
50
- } else {
51
- [context setBlockStyle:BlockTypeParagraph font:_config.paragraphFont color:_config.paragraphColor headingLevel:0];
52
- }
53
-
54
- NSMutableAttributedString *output = [[NSMutableAttributedString alloc] init];
55
-
56
- // 2. Iterate through the sibling nodes.
57
- for (TiptapASTNode *node in nodes) {
58
- [self renderNodeRecursive:node into:output context:context];
59
- }
60
-
61
- // 3. Remove trailing paragraph spacing from last block element
62
- // Reset lastElementMarginBottom before processing
63
- _lastElementMarginBottom = 0.0;
64
- [self removeTrailingSpacing:output];
65
-
66
- // 4. Let the decorator post-process the finished string (e.g. stamp the quote's line height).
67
- [block postProcess:output];
68
- ENRMLinkPillsAdoptPlaceholderFonts(output);
69
-
70
- // 5. Cleanup global state to prevent side effects in subsequent renders.
71
- [context clearBlockStyle];
72
-
73
- return output;
74
- }
75
-
76
- /**
77
- * Trims trailing newlines after the last rendered block, with special handling for code blocks.
78
- *
79
- * For non-code-block tail elements: deletes all trailing newlines after the last non-newline
80
- * character and zeroes the last element's paragraph spacing so it doesn't render a margin past
81
- * the content.
82
- *
83
- * For code blocks (`isLastBlockACodeBlock` == YES): keeps the bottom padding spacer in place
84
- * AND preserves a single trailing newline immediately after it (typically the
85
- * codeBlockMarginBottom spacer that CodeBlockRenderer already appended; if none exists, one is
86
- * synthesized here). That extra newline matters because of an iOS layout quirk:
87
- *
88
- * - iOS treats the trailing `\n` of the storage as a paragraph terminator and reports the
89
- * line fragment for the paragraph after it via `extraLineFragmentRect`.
90
- * - `boundingRectForGlyphRange:` excludes that extra line, and the graphics-context clip
91
- * passed to `drawBackgroundForGlyphRange:` is tiled to the laid-out content area (rounded
92
- * up to 128pt boundaries) which also excludes it.
93
- * - If the bottom padding spacer were the trailing `\n`, its 16/19pt line fragment would
94
- * fall into that excluded zone — the background rect would have to be manually extended
95
- * past the clip and the bottom rounded corner would get sliced off at the tile boundary
96
- * (the original visual bug in #354).
97
- *
98
- * By keeping a 1pt-tall tail newline beyond the bottom padding spacer, iOS lays the spacer
99
- * out as a normal interior line fragment included in usedRect/boundingRect and inside the
100
- * drawing tiles, so the corner renders intact and no rect extension is needed.
101
- */
102
- - (void)removeTrailingSpacing:(NSMutableAttributedString *)output
103
- {
104
- if (output.length == 0)
105
- return;
106
-
107
- // Find the last non-newline character
108
- NSRange lastContent = [output.string rangeOfCharacterFromSet:[NSCharacterSet.newlineCharacterSet invertedSet]
109
- options:NSBackwardsSearch];
110
- if (lastContent.location == NSNotFound)
111
- return;
112
-
113
- // 1. Capture the Margin Bottom (Scanning from last content to end)
114
- _lastElementMarginBottom = 0.0;
115
- for (NSUInteger i = lastContent.location; i < output.length;) {
116
- NSRange attrRange;
117
- NSParagraphStyle *style = [output attribute:NSParagraphStyleAttributeName atIndex:i effectiveRange:&attrRange];
118
- if (style) {
119
- _lastElementMarginBottom = MAX(_lastElementMarginBottom, style.paragraphSpacing);
120
- }
121
- i = NSMaxRange(attrRange);
122
- }
123
-
124
- // 2. Trim trailing characters
125
- NSUInteger logicalEnd = NSMaxRange(lastContent);
126
- BOOL isCodeBlock = isLastBlockACodeBlock(output);
127
- BOOL isPaddedBlockquote = !isCodeBlock && [_config blockquotePadding] > 0 &&
128
- [output attribute:BlockquoteDepthAttributeName
129
- atIndex:lastContent.location
130
- effectiveRange:NULL] != nil;
131
- NSRange codeRange = NSMakeRange(0, 0);
132
- if (isCodeBlock) {
133
- [output attribute:CodeBlockAttributeName
134
- atIndex:lastContent.location
135
- longestEffectiveRange:&codeRange
136
- inRange:NSMakeRange(0, output.length)];
137
- NSUInteger codeEnd = NSMaxRange(codeRange);
138
- if (codeEnd >= output.length) {
139
- [output appendAttributedString:kNewlineAttributedString];
140
- }
141
- logicalEnd = codeEnd + 1;
142
- } else if (isPaddedBlockquote) {
143
- NSUInteger blockquoteEnd = NSMaxRange(lastContent);
144
- while (blockquoteEnd < output.length && [output attribute:BlockquoteDepthAttributeName
145
- atIndex:blockquoteEnd
146
- effectiveRange:NULL] != nil) {
147
- blockquoteEnd++;
148
- }
149
- if (blockquoteEnd >= output.length) {
150
- [output appendAttributedString:kNewlineAttributedString];
151
- }
152
- logicalEnd = blockquoteEnd + 1;
153
- }
154
-
155
- if (logicalEnd < output.length) {
156
- [output deleteCharactersInRange:NSMakeRange(logicalEnd, output.length - logicalEnd)];
157
- }
158
-
159
- if ((isCodeBlock && NSMaxRange(codeRange) < output.length) || isPaddedBlockquote) {
160
- NSUInteger tailIdx = isCodeBlock ? NSMaxRange(codeRange) : logicalEnd - 1;
161
- [output removeAttribute:CodeBlockAttributeName range:NSMakeRange(tailIdx, 1)];
162
- [output removeAttribute:BlockquoteDepthAttributeName range:NSMakeRange(tailIdx, 1)];
163
- [output removeAttribute:BlockquoteBackgroundColorAttributeName range:NSMakeRange(tailIdx, 1)];
164
- NSParagraphStyle *style = [output attribute:NSParagraphStyleAttributeName atIndex:tailIdx effectiveRange:NULL];
165
- NSMutableParagraphStyle *mutableStyle = style ? [style mutableCopy] : [[NSMutableParagraphStyle alloc] init];
166
- mutableStyle.paragraphSpacing = 0;
167
- mutableStyle.paragraphSpacingBefore = 0;
168
- mutableStyle.minimumLineHeight = 1;
169
- mutableStyle.maximumLineHeight = 1;
170
- [output addAttribute:NSParagraphStyleAttributeName value:mutableStyle range:NSMakeRange(tailIdx, 1)];
171
- }
172
-
173
- // 3. Zero out internal spacing for the last element (if not a code block)
174
- if (!isCodeBlock) {
175
- NSRange styleRange;
176
- NSParagraphStyle *style = [output attribute:NSParagraphStyleAttributeName
177
- atIndex:lastContent.location
178
- effectiveRange:&styleRange];
179
-
180
- if (style) {
181
- NSMutableParagraphStyle *mutableStyle = [style mutableCopy];
182
- mutableStyle.paragraphSpacing = 0;
183
- mutableStyle.paragraphSpacingBefore = 0;
184
-
185
- if (isLastElementImage(output)) {
186
- mutableStyle.lineSpacing = 0;
187
- }
188
-
189
- NSRange safeRange = NSIntersectionRange(styleRange, NSMakeRange(0, output.length));
190
- [output addAttribute:NSParagraphStyleAttributeName value:mutableStyle range:safeRange];
191
- }
192
- }
193
- }
194
-
195
- - (void)setAllowTrailingMargin:(BOOL)allow
196
- {
197
- _allowTrailingMargin = allow;
198
- }
199
-
200
- - (CGFloat)getLastElementMarginBottom
201
- {
202
- return _lastElementMarginBottom;
203
- }
204
-
205
- /**
206
- * Orchestrates the recursive traversal of the AST.
207
- * If a specialized renderer exists for a node type, it takes full control.
208
- */
209
- - (void)renderNodeRecursive:(TiptapASTNode *)node
210
- into:(NSMutableAttributedString *)out
211
- context:(RenderContext *)context
212
- {
213
- if (!node)
214
- return;
215
-
216
- id<NodeRenderer> renderer = [_rendererFactory rendererForNodeType:node.type];
217
-
218
- if (renderer) {
219
- // Specialized renderers (e.g., Strong, Link, Heading) handle their own sub-trees.
220
- [renderer renderNode:node into:out context:context];
221
- } else {
222
- // Fallback: Default to deep-first traversal for unhandled container nodes.
223
- for (TiptapASTNode *child in node.children) {
224
- [self renderNodeRecursive:child into:out context:context];
225
- }
226
- }
227
- }
228
-
229
- @end
1
+ #import "AttributedRenderer.h"
2
+ #import "BlockquoteBorder.h"
3
+ #import "CodeBlockBackground.h"
4
+ #import "ENRMBlockquoteTextRenderer.h"
5
+ #import "ENRMLinkPillText.h"
6
+ #import "LastElementUtils.h"
7
+ #import "TiptapASTNode.h"
8
+ #import "NodeRenderer.h"
9
+ #import "ParagraphStyleUtils.h"
10
+ #import "RenderContext.h"
11
+ #import "RendererFactory.h"
12
+ #import "StyleConfig.h"
13
+
14
+ @implementation AttributedRenderer {
15
+ StyleConfig *_config;
16
+ RendererFactory *_rendererFactory;
17
+ CGFloat _lastElementMarginBottom;
18
+ BOOL _allowTrailingMargin;
19
+ }
20
+
21
+ - (instancetype)initWithConfig:(StyleConfig *)config
22
+ {
23
+ self = [super init];
24
+ if (self) {
25
+ _config = config;
26
+ _rendererFactory = [[RendererFactory alloc] initWithConfig:config];
27
+ _lastElementMarginBottom = 0.0;
28
+ _allowTrailingMargin = NO;
29
+ }
30
+ return self;
31
+ }
32
+
33
+ /**
34
+ * Entry point for rendering a flat list of sibling nodes (e.g. a document's or a block segment's
35
+ * children). Sets the baseline block style, runs the recursive traversal, and trims the trailing
36
+ * block margin. An optional [block] decorates the pass - it enters a block baseline before the nodes
37
+ * render and post-processes the finished string - letting a caller render content as e.g. blockquote
38
+ * text without this class knowing anything block-specific. See ENRMBlockquoteTextRenderer.
39
+ */
40
+ - (NSMutableAttributedString *)renderNodes:(NSArray<TiptapASTNode *> *)nodes
41
+ context:(RenderContext *)context
42
+ block:(ENRMBlockquoteTextRenderer *)block
43
+ {
44
+ // 1. Establish the baseline block style. This ensures leaf nodes (like Text) have valid
45
+ // attributes if they appear at the top level. A decorator overrides the default paragraph
46
+ // baseline (e.g. the blockquote baseline so paragraphs render tight and pick up the quote's
47
+ // font/color).
48
+ if (block) {
49
+ [block pushOnContext:context];
50
+ } else {
51
+ [context setBlockStyle:BlockTypeParagraph font:_config.paragraphFont color:_config.paragraphColor headingLevel:0];
52
+ }
53
+
54
+ NSMutableAttributedString *output = [[NSMutableAttributedString alloc] init];
55
+
56
+ // 2. Iterate through the sibling nodes.
57
+ for (TiptapASTNode *node in nodes) {
58
+ [self renderNodeRecursive:node into:output context:context];
59
+ }
60
+
61
+ // 3. Remove trailing paragraph spacing from last block element
62
+ // Reset lastElementMarginBottom before processing
63
+ _lastElementMarginBottom = 0.0;
64
+ [self removeTrailingSpacing:output];
65
+
66
+ // 4. Let the decorator post-process the finished string (e.g. stamp the quote's line height).
67
+ [block postProcess:output];
68
+ ENRMLinkPillsAdoptPlaceholderFonts(output);
69
+
70
+ // 5. Cleanup global state to prevent side effects in subsequent renders.
71
+ [context clearBlockStyle];
72
+
73
+ return output;
74
+ }
75
+
76
+ /**
77
+ * Trims trailing newlines after the last rendered block, with special handling for code blocks.
78
+ *
79
+ * For non-code-block tail elements: deletes all trailing newlines after the last non-newline
80
+ * character and zeroes the last element's paragraph spacing so it doesn't render a margin past
81
+ * the content.
82
+ *
83
+ * For code blocks (`isLastBlockACodeBlock` == YES): keeps the bottom padding spacer in place
84
+ * AND preserves a single trailing newline immediately after it (typically the
85
+ * codeBlockMarginBottom spacer that CodeBlockRenderer already appended; if none exists, one is
86
+ * synthesized here). That extra newline matters because of an iOS layout quirk:
87
+ *
88
+ * - iOS treats the trailing `\n` of the storage as a paragraph terminator and reports the
89
+ * line fragment for the paragraph after it via `extraLineFragmentRect`.
90
+ * - `boundingRectForGlyphRange:` excludes that extra line, and the graphics-context clip
91
+ * passed to `drawBackgroundForGlyphRange:` is tiled to the laid-out content area (rounded
92
+ * up to 128pt boundaries) which also excludes it.
93
+ * - If the bottom padding spacer were the trailing `\n`, its 16/19pt line fragment would
94
+ * fall into that excluded zone — the background rect would have to be manually extended
95
+ * past the clip and the bottom rounded corner would get sliced off at the tile boundary
96
+ * (the original visual bug in #354).
97
+ *
98
+ * By keeping a 1pt-tall tail newline beyond the bottom padding spacer, iOS lays the spacer
99
+ * out as a normal interior line fragment included in usedRect/boundingRect and inside the
100
+ * drawing tiles, so the corner renders intact and no rect extension is needed.
101
+ */
102
+ - (void)removeTrailingSpacing:(NSMutableAttributedString *)output
103
+ {
104
+ if (output.length == 0)
105
+ return;
106
+
107
+ // Find the last non-newline character
108
+ NSRange lastContent = [output.string rangeOfCharacterFromSet:[NSCharacterSet.newlineCharacterSet invertedSet]
109
+ options:NSBackwardsSearch];
110
+ if (lastContent.location == NSNotFound)
111
+ return;
112
+
113
+ // 1. Capture the Margin Bottom (Scanning from last content to end)
114
+ _lastElementMarginBottom = 0.0;
115
+ for (NSUInteger i = lastContent.location; i < output.length;) {
116
+ NSRange attrRange;
117
+ NSParagraphStyle *style = [output attribute:NSParagraphStyleAttributeName atIndex:i effectiveRange:&attrRange];
118
+ if (style) {
119
+ _lastElementMarginBottom = MAX(_lastElementMarginBottom, style.paragraphSpacing);
120
+ }
121
+ i = NSMaxRange(attrRange);
122
+ }
123
+
124
+ // 2. Trim trailing characters
125
+ NSUInteger logicalEnd = NSMaxRange(lastContent);
126
+ BOOL isCodeBlock = isLastBlockACodeBlock(output);
127
+ BOOL isPaddedBlockquote = !isCodeBlock && [_config blockquotePadding] > 0 &&
128
+ [output attribute:BlockquoteDepthAttributeName
129
+ atIndex:lastContent.location
130
+ effectiveRange:NULL] != nil;
131
+ NSRange codeRange = NSMakeRange(0, 0);
132
+ if (isCodeBlock) {
133
+ [output attribute:CodeBlockAttributeName
134
+ atIndex:lastContent.location
135
+ longestEffectiveRange:&codeRange
136
+ inRange:NSMakeRange(0, output.length)];
137
+ NSUInteger codeEnd = NSMaxRange(codeRange);
138
+ if (codeEnd >= output.length) {
139
+ [output appendAttributedString:kNewlineAttributedString];
140
+ }
141
+ logicalEnd = codeEnd + 1;
142
+ } else if (isPaddedBlockquote) {
143
+ NSUInteger blockquoteEnd = NSMaxRange(lastContent);
144
+ while (blockquoteEnd < output.length && [output attribute:BlockquoteDepthAttributeName
145
+ atIndex:blockquoteEnd
146
+ effectiveRange:NULL] != nil) {
147
+ blockquoteEnd++;
148
+ }
149
+ if (blockquoteEnd >= output.length) {
150
+ [output appendAttributedString:kNewlineAttributedString];
151
+ }
152
+ logicalEnd = blockquoteEnd + 1;
153
+ }
154
+
155
+ if (logicalEnd < output.length) {
156
+ [output deleteCharactersInRange:NSMakeRange(logicalEnd, output.length - logicalEnd)];
157
+ }
158
+
159
+ if ((isCodeBlock && NSMaxRange(codeRange) < output.length) || isPaddedBlockquote) {
160
+ NSUInteger tailIdx = isCodeBlock ? NSMaxRange(codeRange) : logicalEnd - 1;
161
+ [output removeAttribute:CodeBlockAttributeName range:NSMakeRange(tailIdx, 1)];
162
+ [output removeAttribute:BlockquoteDepthAttributeName range:NSMakeRange(tailIdx, 1)];
163
+ [output removeAttribute:BlockquoteBackgroundColorAttributeName range:NSMakeRange(tailIdx, 1)];
164
+ NSParagraphStyle *style = [output attribute:NSParagraphStyleAttributeName atIndex:tailIdx effectiveRange:NULL];
165
+ NSMutableParagraphStyle *mutableStyle = style ? [style mutableCopy] : [[NSMutableParagraphStyle alloc] init];
166
+ mutableStyle.paragraphSpacing = 0;
167
+ mutableStyle.paragraphSpacingBefore = 0;
168
+ mutableStyle.minimumLineHeight = 1;
169
+ mutableStyle.maximumLineHeight = 1;
170
+ [output addAttribute:NSParagraphStyleAttributeName value:mutableStyle range:NSMakeRange(tailIdx, 1)];
171
+ }
172
+
173
+ // 3. Zero out internal spacing for the last element (if not a code block)
174
+ if (!isCodeBlock) {
175
+ NSRange styleRange;
176
+ NSParagraphStyle *style = [output attribute:NSParagraphStyleAttributeName
177
+ atIndex:lastContent.location
178
+ effectiveRange:&styleRange];
179
+
180
+ if (style) {
181
+ NSMutableParagraphStyle *mutableStyle = [style mutableCopy];
182
+ mutableStyle.paragraphSpacing = 0;
183
+ mutableStyle.paragraphSpacingBefore = 0;
184
+
185
+ if (isLastElementImage(output)) {
186
+ mutableStyle.lineSpacing = 0;
187
+ }
188
+
189
+ NSRange safeRange = NSIntersectionRange(styleRange, NSMakeRange(0, output.length));
190
+ [output addAttribute:NSParagraphStyleAttributeName value:mutableStyle range:safeRange];
191
+ }
192
+ }
193
+ }
194
+
195
+ - (void)setAllowTrailingMargin:(BOOL)allow
196
+ {
197
+ _allowTrailingMargin = allow;
198
+ }
199
+
200
+ - (CGFloat)getLastElementMarginBottom
201
+ {
202
+ return _lastElementMarginBottom;
203
+ }
204
+
205
+ /**
206
+ * Orchestrates the recursive traversal of the AST.
207
+ * If a specialized renderer exists for a node type, it takes full control.
208
+ */
209
+ - (void)renderNodeRecursive:(TiptapASTNode *)node
210
+ into:(NSMutableAttributedString *)out
211
+ context:(RenderContext *)context
212
+ {
213
+ if (!node)
214
+ return;
215
+
216
+ id<NodeRenderer> renderer = [_rendererFactory rendererForNodeType:node.type];
217
+
218
+ if (renderer) {
219
+ // Specialized renderers (e.g., Strong, Link, Heading) handle their own sub-trees.
220
+ [renderer renderNode:node into:out context:context];
221
+ } else {
222
+ // Fallback: Default to deep-first traversal for unhandled container nodes.
223
+ for (TiptapASTNode *child in node.children) {
224
+ [self renderNodeRecursive:child into:out context:context];
225
+ }
226
+ }
227
+ }
228
+
229
+ @end
@@ -1,33 +1,33 @@
1
- #pragma once
2
- #import "NodeRenderer.h"
3
-
4
- @class RendererFactory;
5
- @class StyleConfig;
6
- @class RenderContext;
7
- @class TiptapASTNode;
8
-
9
- /// Shared base for all node renderers — provides `_rendererFactory` and `_config`
10
- /// as protected ivars and the common designated initializer.
11
- /// `renderNode:into:context:` is a template method: take context snapshot ->
12
- /// `renderNodeContent:into:context:` -> restore snapshot. Subclasses implement
13
- /// `renderNodeContent:into:context:` and, when they mutate scoped context state,
14
- /// override `takeContextSnapshot:` to return `[context snapshotScope]`.
15
- @interface BaseRenderer : NSObject <NodeRenderer> {
16
- @protected
17
- __weak RendererFactory *_rendererFactory;
18
- StyleConfig *_config;
19
- }
20
-
21
- - (instancetype)initWithRendererFactory:(id)rendererFactory config:(id)config;
22
-
23
- - (void)renderNodeContent:(TiptapASTNode *)node
24
- into:(NSMutableAttributedString *)output
25
- context:(RenderContext *)context;
26
-
27
- /// Default returns nil.
28
- - (nullable id)takeContextSnapshot:(RenderContext *)context;
29
-
30
- /// Default restores a scope frame when snapshot is non-nil, no-op otherwise.
31
- - (void)restoreContextSnapshot:(nullable id)snapshot context:(RenderContext *)context;
32
-
33
- @end
1
+ #pragma once
2
+ #import "NodeRenderer.h"
3
+
4
+ @class RendererFactory;
5
+ @class StyleConfig;
6
+ @class RenderContext;
7
+ @class TiptapASTNode;
8
+
9
+ /// Shared base for all node renderers — provides `_rendererFactory` and `_config`
10
+ /// as protected ivars and the common designated initializer.
11
+ /// `renderNode:into:context:` is a template method: take context snapshot ->
12
+ /// `renderNodeContent:into:context:` -> restore snapshot. Subclasses implement
13
+ /// `renderNodeContent:into:context:` and, when they mutate scoped context state,
14
+ /// override `takeContextSnapshot:` to return `[context snapshotScope]`.
15
+ @interface BaseRenderer : NSObject <NodeRenderer> {
16
+ @protected
17
+ __weak RendererFactory *_rendererFactory;
18
+ StyleConfig *_config;
19
+ }
20
+
21
+ - (instancetype)initWithRendererFactory:(id)rendererFactory config:(id)config;
22
+
23
+ - (void)renderNodeContent:(TiptapASTNode *)node
24
+ into:(NSMutableAttributedString *)output
25
+ context:(RenderContext *)context;
26
+
27
+ /// Default returns nil.
28
+ - (nullable id)takeContextSnapshot:(RenderContext *)context;
29
+
30
+ /// Default restores a scope frame when snapshot is non-nil, no-op otherwise.
31
+ - (void)restoreContextSnapshot:(nullable id)snapshot context:(RenderContext *)context;
32
+
33
+ @end