@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,235 +1,235 @@
1
- package com.renderrichtext.utils.text.view
2
-
3
- import android.content.ClipData
4
- import android.content.ClipboardManager
5
- import android.content.Context
6
- import android.text.Spannable
7
- import android.view.ActionMode
8
- import android.view.Menu
9
- import android.view.MenuItem
10
- import android.view.ViewParent
11
- import android.widget.TextView
12
- import com.renderrichtext.EnrichedTiptapText
13
- import com.renderrichtext.spans.ImageSpan
14
- import com.renderrichtext.spans.stripFactoidPadding
15
- import com.renderrichtext.styles.StyleConfig
16
- import com.renderrichtext.utils.common.layout.isLayoutRTL
17
- import com.renderrichtext.utils.text.conversion.HTMLGenerator
18
- import com.renderrichtext.utils.text.conversion.TiptapExtractor
19
-
20
- private const val MENU_ITEM_COPY_TIPTAP = 1000
21
- private const val MENU_ITEM_COPY_IMAGE_URL = 1001
22
- private const val MENU_ITEM_CUSTOM_BASE = 2000
23
- private const val MENU_ITEM_CUSTOM_GROUP = 2001
24
-
25
- data class SelectionMenuConfig(
26
- val copyAsTiptap: Boolean = true,
27
- val copyImageUrl: Boolean = true,
28
- val copyLabel: String = "",
29
- val copyAsTiptapLabel: String = "",
30
- val copyImageUrlLabel: String = "",
31
- val copyImageUrlsLabel: String = "",
32
- // Plural templates indexed by image count (0..100). Empty when no pluralLabels
33
- // are set; counts > 100 use copyImageUrlsLabel (the "other" form).
34
- val copyImageUrlPluralTemplates: List<String> = emptyList(),
35
- )
36
-
37
- /**
38
- * Resolves the "Copy Image URL(s)" menu title for the given image count. Uses the
39
- * precomputed plural templates when present (counts > 100 use the "other" form),
40
- * otherwise the singular/`{count}` templates. All labels are resolved JS-side.
41
- */
42
- private fun SelectionMenuConfig.imageUrlsTitle(count: Int): String {
43
- val template =
44
- when {
45
- copyImageUrlPluralTemplates.isNotEmpty() && count in 0..100 -> copyImageUrlPluralTemplates[count]
46
- count == 1 -> copyImageUrlLabel
47
- else -> copyImageUrlsLabel
48
- }
49
- return template.replace("{count}", count.toString())
50
- }
51
-
52
- /**
53
- * Creates an ActionMode.Callback that adds custom copy options and
54
- * overrides the default "Copy" action to include HTML for rich text support.
55
- */
56
- fun createSelectionActionModeCallback(
57
- textView: TextView,
58
- getCustomItemTexts: () -> List<String> = { emptyList() },
59
- getSelectionMenuConfig: () -> SelectionMenuConfig = { SelectionMenuConfig() },
60
- onCustomItemPress: (itemText: String, selectedText: String, selectionStart: Int, selectionEnd: Int) -> Unit =
61
- { _, _, _, _ -> },
62
- ): ActionMode.Callback =
63
- object : ActionMode.Callback {
64
- override fun onCreateActionMode(
65
- mode: ActionMode?,
66
- menu: Menu?,
67
- ): Boolean = true
68
-
69
- override fun onPrepareActionMode(
70
- mode: ActionMode?,
71
- menu: Menu?,
72
- ): Boolean {
73
- if (menu == null) return false
74
-
75
- menu.removeItem(MENU_ITEM_COPY_TIPTAP)
76
- menu.removeItem(MENU_ITEM_COPY_IMAGE_URL)
77
- menu.removeGroup(MENU_ITEM_CUSTOM_GROUP)
78
-
79
- val selectionMenuConfig = getSelectionMenuConfig()
80
-
81
- // The system Copy item is added by the platform; relabel it so it
82
- // matches the rest of the localized menu (iOS rebuilds the menu so
83
- // gets this for free; Android only intercepts the click).
84
- if (selectionMenuConfig.copyLabel.isNotEmpty()) {
85
- menu.findItem(android.R.id.copy)?.title = selectionMenuConfig.copyLabel
86
- }
87
-
88
- if (
89
- selectionMenuConfig.copyAsTiptap &&
90
- textView.selectionStart >= 0 &&
91
- textView.selectionEnd > textView.selectionStart
92
- ) {
93
- menu.add(
94
- Menu.NONE,
95
- MENU_ITEM_COPY_TIPTAP,
96
- Menu.NONE,
97
- selectionMenuConfig.copyAsTiptapLabel,
98
- )
99
- }
100
-
101
- if (textView.selectionStart >= 0 && textView.selectionEnd > textView.selectionStart) {
102
- val customItems = getCustomItemTexts()
103
- customItems.forEachIndexed { index, text ->
104
- menu
105
- .add(MENU_ITEM_CUSTOM_GROUP, MENU_ITEM_CUSTOM_BASE + index, index, text)
106
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
107
- }
108
- }
109
-
110
- val imageUrls =
111
- if (selectionMenuConfig.copyImageUrl) {
112
- textView.getImageUrlsInSelection()
113
- } else {
114
- emptyList()
115
- }
116
- if (imageUrls.isNotEmpty()) {
117
- val title = selectionMenuConfig.imageUrlsTitle(imageUrls.size)
118
- menu.add(Menu.NONE, MENU_ITEM_COPY_IMAGE_URL, Menu.NONE, title)
119
- }
120
-
121
- return true
122
- }
123
-
124
- override fun onActionItemClicked(
125
- mode: ActionMode?,
126
- item: MenuItem?,
127
- ): Boolean {
128
- val itemId = item?.itemId ?: return false
129
-
130
- when (itemId) {
131
- android.R.id.copy -> {
132
- textView.copyWithHTML()
133
- mode?.finish()
134
- return true
135
- }
136
-
137
- MENU_ITEM_COPY_TIPTAP -> {
138
- textView.copyTiptapToClipboard()
139
- mode?.finish()
140
- return true
141
- }
142
-
143
- MENU_ITEM_COPY_IMAGE_URL -> {
144
- textView.copyImageUrlsToClipboard()
145
- mode?.finish()
146
- return true
147
- }
148
- }
149
-
150
- val customItems = getCustomItemTexts()
151
- val customIndex = itemId - MENU_ITEM_CUSTOM_BASE
152
- if (customIndex in customItems.indices) {
153
- val start = textView.selectionStart
154
- val end = textView.selectionEnd
155
- val selectedText =
156
- if (start >= 0 && end > start) textView.text.subSequence(start, end).stripFactoidPadding() else ""
157
- onCustomItemPress(customItems[customIndex], selectedText, start, end)
158
- mode?.finish()
159
- return true
160
- }
161
-
162
- return false
163
- }
164
-
165
- override fun onDestroyActionMode(mode: ActionMode?) {}
166
- }
167
-
168
- /** Copies selection as both plain text and HTML with inline styles. */
169
- private fun TextView.copyWithHTML() {
170
- val start = selectionStart
171
- val end = selectionEnd
172
- if (start < 0 || end < 0 || start >= end) return
173
-
174
- val spannable = text as? Spannable ?: return
175
- val selectedText = spannable.subSequence(start, end)
176
- val plainText = selectedText.stripFactoidPadding()
177
-
178
- val styleConfig =
179
- (this as? EnrichedTiptapText)?.tiptapStyle
180
- ?: findParentTiptapStyle()
181
- val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
182
-
183
- if (styleConfig != null && selectedText is Spannable) {
184
- // Density values convert device pixels back to CSS pixels
185
- val displayMetrics = context.resources.displayMetrics
186
- val isRTL = context.resources.isLayoutRTL()
187
- val html =
188
- HTMLGenerator.generateHTML(
189
- selectedText,
190
- styleConfig,
191
- displayMetrics.scaledDensity,
192
- displayMetrics.density,
193
- isRTL,
194
- )
195
- clipboard.setPrimaryClip(ClipData.newHtmlText("EnrichedTiptap", plainText, html))
196
- } else {
197
- clipboard.setPrimaryClip(ClipData.newPlainText("Text", plainText))
198
- }
199
- }
200
-
201
- private fun TextView.copyTiptapToClipboard() {
202
- val tiptap = TiptapExtractor.getTiptapForSelection(this) ?: return
203
- val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
204
- clipboard.setPrimaryClip(ClipData.newPlainText("Tiptap", tiptap))
205
- }
206
-
207
- /** Returns remote image URLs (http/https only) from the current selection. */
208
- private fun TextView.getImageUrlsInSelection(): List<String> {
209
- val start = selectionStart
210
- val end = selectionEnd
211
- if (start < 0 || end < 0 || start >= end) return emptyList()
212
-
213
- val spannable = text as? Spannable ?: return emptyList()
214
- return spannable
215
- .getSpans(start, end, ImageSpan::class.java)
216
- .mapNotNull { it.imageUrl }
217
- .filter { it.startsWith("http://") || it.startsWith("https://") }
218
- }
219
-
220
- private fun TextView.copyImageUrlsToClipboard() {
221
- val urls = getImageUrlsInSelection()
222
- if (urls.isEmpty()) return
223
-
224
- val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
225
- clipboard.setPrimaryClip(ClipData.newPlainText("Image URLs", urls.joinToString("\n")))
226
- }
227
-
228
- private fun TextView.findParentTiptapStyle(): StyleConfig? {
229
- var current: ViewParent? = parent
230
- while (current != null) {
231
- if (current is EnrichedTiptapText) return current.tiptapStyle
232
- current = current.parent
233
- }
234
- return null
235
- }
1
+ package com.renderrichtext.utils.text.view
2
+
3
+ import android.content.ClipData
4
+ import android.content.ClipboardManager
5
+ import android.content.Context
6
+ import android.text.Spannable
7
+ import android.view.ActionMode
8
+ import android.view.Menu
9
+ import android.view.MenuItem
10
+ import android.view.ViewParent
11
+ import android.widget.TextView
12
+ import com.renderrichtext.EnrichedTiptapText
13
+ import com.renderrichtext.spans.ImageSpan
14
+ import com.renderrichtext.spans.stripFactoidPadding
15
+ import com.renderrichtext.styles.StyleConfig
16
+ import com.renderrichtext.utils.common.layout.isLayoutRTL
17
+ import com.renderrichtext.utils.text.conversion.HTMLGenerator
18
+ import com.renderrichtext.utils.text.conversion.TiptapExtractor
19
+
20
+ private const val MENU_ITEM_COPY_TIPTAP = 1000
21
+ private const val MENU_ITEM_COPY_IMAGE_URL = 1001
22
+ private const val MENU_ITEM_CUSTOM_BASE = 2000
23
+ private const val MENU_ITEM_CUSTOM_GROUP = 2001
24
+
25
+ data class SelectionMenuConfig(
26
+ val copyAsTiptap: Boolean = true,
27
+ val copyImageUrl: Boolean = true,
28
+ val copyLabel: String = "",
29
+ val copyAsTiptapLabel: String = "",
30
+ val copyImageUrlLabel: String = "",
31
+ val copyImageUrlsLabel: String = "",
32
+ // Plural templates indexed by image count (0..100). Empty when no pluralLabels
33
+ // are set; counts > 100 use copyImageUrlsLabel (the "other" form).
34
+ val copyImageUrlPluralTemplates: List<String> = emptyList(),
35
+ )
36
+
37
+ /**
38
+ * Resolves the "Copy Image URL(s)" menu title for the given image count. Uses the
39
+ * precomputed plural templates when present (counts > 100 use the "other" form),
40
+ * otherwise the singular/`{count}` templates. All labels are resolved JS-side.
41
+ */
42
+ private fun SelectionMenuConfig.imageUrlsTitle(count: Int): String {
43
+ val template =
44
+ when {
45
+ copyImageUrlPluralTemplates.isNotEmpty() && count in 0..100 -> copyImageUrlPluralTemplates[count]
46
+ count == 1 -> copyImageUrlLabel
47
+ else -> copyImageUrlsLabel
48
+ }
49
+ return template.replace("{count}", count.toString())
50
+ }
51
+
52
+ /**
53
+ * Creates an ActionMode.Callback that adds custom copy options and
54
+ * overrides the default "Copy" action to include HTML for rich text support.
55
+ */
56
+ fun createSelectionActionModeCallback(
57
+ textView: TextView,
58
+ getCustomItemTexts: () -> List<String> = { emptyList() },
59
+ getSelectionMenuConfig: () -> SelectionMenuConfig = { SelectionMenuConfig() },
60
+ onCustomItemPress: (itemText: String, selectedText: String, selectionStart: Int, selectionEnd: Int) -> Unit =
61
+ { _, _, _, _ -> },
62
+ ): ActionMode.Callback =
63
+ object : ActionMode.Callback {
64
+ override fun onCreateActionMode(
65
+ mode: ActionMode?,
66
+ menu: Menu?,
67
+ ): Boolean = true
68
+
69
+ override fun onPrepareActionMode(
70
+ mode: ActionMode?,
71
+ menu: Menu?,
72
+ ): Boolean {
73
+ if (menu == null) return false
74
+
75
+ menu.removeItem(MENU_ITEM_COPY_TIPTAP)
76
+ menu.removeItem(MENU_ITEM_COPY_IMAGE_URL)
77
+ menu.removeGroup(MENU_ITEM_CUSTOM_GROUP)
78
+
79
+ val selectionMenuConfig = getSelectionMenuConfig()
80
+
81
+ // The system Copy item is added by the platform; relabel it so it
82
+ // matches the rest of the localized menu (iOS rebuilds the menu so
83
+ // gets this for free; Android only intercepts the click).
84
+ if (selectionMenuConfig.copyLabel.isNotEmpty()) {
85
+ menu.findItem(android.R.id.copy)?.title = selectionMenuConfig.copyLabel
86
+ }
87
+
88
+ if (
89
+ selectionMenuConfig.copyAsTiptap &&
90
+ textView.selectionStart >= 0 &&
91
+ textView.selectionEnd > textView.selectionStart
92
+ ) {
93
+ menu.add(
94
+ Menu.NONE,
95
+ MENU_ITEM_COPY_TIPTAP,
96
+ Menu.NONE,
97
+ selectionMenuConfig.copyAsTiptapLabel,
98
+ )
99
+ }
100
+
101
+ if (textView.selectionStart >= 0 && textView.selectionEnd > textView.selectionStart) {
102
+ val customItems = getCustomItemTexts()
103
+ customItems.forEachIndexed { index, text ->
104
+ menu
105
+ .add(MENU_ITEM_CUSTOM_GROUP, MENU_ITEM_CUSTOM_BASE + index, index, text)
106
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
107
+ }
108
+ }
109
+
110
+ val imageUrls =
111
+ if (selectionMenuConfig.copyImageUrl) {
112
+ textView.getImageUrlsInSelection()
113
+ } else {
114
+ emptyList()
115
+ }
116
+ if (imageUrls.isNotEmpty()) {
117
+ val title = selectionMenuConfig.imageUrlsTitle(imageUrls.size)
118
+ menu.add(Menu.NONE, MENU_ITEM_COPY_IMAGE_URL, Menu.NONE, title)
119
+ }
120
+
121
+ return true
122
+ }
123
+
124
+ override fun onActionItemClicked(
125
+ mode: ActionMode?,
126
+ item: MenuItem?,
127
+ ): Boolean {
128
+ val itemId = item?.itemId ?: return false
129
+
130
+ when (itemId) {
131
+ android.R.id.copy -> {
132
+ textView.copyWithHTML()
133
+ mode?.finish()
134
+ return true
135
+ }
136
+
137
+ MENU_ITEM_COPY_TIPTAP -> {
138
+ textView.copyTiptapToClipboard()
139
+ mode?.finish()
140
+ return true
141
+ }
142
+
143
+ MENU_ITEM_COPY_IMAGE_URL -> {
144
+ textView.copyImageUrlsToClipboard()
145
+ mode?.finish()
146
+ return true
147
+ }
148
+ }
149
+
150
+ val customItems = getCustomItemTexts()
151
+ val customIndex = itemId - MENU_ITEM_CUSTOM_BASE
152
+ if (customIndex in customItems.indices) {
153
+ val start = textView.selectionStart
154
+ val end = textView.selectionEnd
155
+ val selectedText =
156
+ if (start >= 0 && end > start) textView.text.subSequence(start, end).stripFactoidPadding() else ""
157
+ onCustomItemPress(customItems[customIndex], selectedText, start, end)
158
+ mode?.finish()
159
+ return true
160
+ }
161
+
162
+ return false
163
+ }
164
+
165
+ override fun onDestroyActionMode(mode: ActionMode?) {}
166
+ }
167
+
168
+ /** Copies selection as both plain text and HTML with inline styles. */
169
+ private fun TextView.copyWithHTML() {
170
+ val start = selectionStart
171
+ val end = selectionEnd
172
+ if (start < 0 || end < 0 || start >= end) return
173
+
174
+ val spannable = text as? Spannable ?: return
175
+ val selectedText = spannable.subSequence(start, end)
176
+ val plainText = selectedText.stripFactoidPadding()
177
+
178
+ val styleConfig =
179
+ (this as? EnrichedTiptapText)?.tiptapStyle
180
+ ?: findParentTiptapStyle()
181
+ val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
182
+
183
+ if (styleConfig != null && selectedText is Spannable) {
184
+ // Density values convert device pixels back to CSS pixels
185
+ val displayMetrics = context.resources.displayMetrics
186
+ val isRTL = context.resources.isLayoutRTL()
187
+ val html =
188
+ HTMLGenerator.generateHTML(
189
+ selectedText,
190
+ styleConfig,
191
+ displayMetrics.scaledDensity,
192
+ displayMetrics.density,
193
+ isRTL,
194
+ )
195
+ clipboard.setPrimaryClip(ClipData.newHtmlText("EnrichedTiptap", plainText, html))
196
+ } else {
197
+ clipboard.setPrimaryClip(ClipData.newPlainText("Text", plainText))
198
+ }
199
+ }
200
+
201
+ private fun TextView.copyTiptapToClipboard() {
202
+ val tiptap = TiptapExtractor.getTiptapForSelection(this) ?: return
203
+ val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
204
+ clipboard.setPrimaryClip(ClipData.newPlainText("Tiptap", tiptap))
205
+ }
206
+
207
+ /** Returns remote image URLs (http/https only) from the current selection. */
208
+ private fun TextView.getImageUrlsInSelection(): List<String> {
209
+ val start = selectionStart
210
+ val end = selectionEnd
211
+ if (start < 0 || end < 0 || start >= end) return emptyList()
212
+
213
+ val spannable = text as? Spannable ?: return emptyList()
214
+ return spannable
215
+ .getSpans(start, end, ImageSpan::class.java)
216
+ .mapNotNull { it.imageUrl }
217
+ .filter { it.startsWith("http://") || it.startsWith("https://") }
218
+ }
219
+
220
+ private fun TextView.copyImageUrlsToClipboard() {
221
+ val urls = getImageUrlsInSelection()
222
+ if (urls.isEmpty()) return
223
+
224
+ val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
225
+ clipboard.setPrimaryClip(ClipData.newPlainText("Image URLs", urls.joinToString("\n")))
226
+ }
227
+
228
+ private fun TextView.findParentTiptapStyle(): StyleConfig? {
229
+ var current: ViewParent? = parent
230
+ while (current != null) {
231
+ if (current is EnrichedTiptapText) return current.tiptapStyle
232
+ current = current.parent
233
+ }
234
+ return null
235
+ }
@@ -1,48 +1,48 @@
1
- package com.renderrichtext.utils.text.view
2
-
3
- import android.graphics.drawable.Drawable
4
- import android.os.Build
5
- import android.util.Log
6
- import android.widget.TextView
7
- import androidx.annotation.ColorInt
8
- import androidx.core.graphics.drawable.DrawableCompat
9
-
10
- private const val TAG = "TextSelectionColors"
11
-
12
- private typealias HandleGetter = (TextView) -> Drawable?
13
- private typealias HandleSetter = (TextView, Drawable) -> Unit
14
-
15
- /**
16
- * Applies selection highlight and (where supported) handle tinting to a [TextView].
17
- *
18
- * Handle drawables are only tinted on API 29+ where the framework exposes getters;
19
- * on older versions the handle theme defaults remain unchanged.
20
- */
21
- fun TextView.applySelectionColors(
22
- selectionColor: Int?,
23
- selectionHandleColor: Int?,
24
- ) {
25
- selectionColor?.let { highlightColor = it }
26
- selectionHandleColor?.let { applySelectionHandleTint(it) }
27
- }
28
-
29
- private fun TextView.applySelectionHandleTint(
30
- @ColorInt color: Int,
31
- ) {
32
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) return
33
-
34
- val handles: List<Pair<HandleGetter, HandleSetter>> =
35
- listOf(
36
- TextView::getTextSelectHandleLeft to { tv, d -> tv.setTextSelectHandleLeft(d) },
37
- TextView::getTextSelectHandle to { tv, d -> tv.setTextSelectHandle(d) },
38
- TextView::getTextSelectHandleRight to { tv, d -> tv.setTextSelectHandleRight(d) },
39
- )
40
-
41
- handles.forEach { (getter, setter) ->
42
- try {
43
- getter(this)?.mutate()?.also { DrawableCompat.setTint(it, color) }?.let { setter(this, it) }
44
- } catch (e: LinkageError) {
45
- Log.w(TAG, "Selection handle tint skipped: ${e.message}")
46
- }
47
- }
48
- }
1
+ package com.renderrichtext.utils.text.view
2
+
3
+ import android.graphics.drawable.Drawable
4
+ import android.os.Build
5
+ import android.util.Log
6
+ import android.widget.TextView
7
+ import androidx.annotation.ColorInt
8
+ import androidx.core.graphics.drawable.DrawableCompat
9
+
10
+ private const val TAG = "TextSelectionColors"
11
+
12
+ private typealias HandleGetter = (TextView) -> Drawable?
13
+ private typealias HandleSetter = (TextView, Drawable) -> Unit
14
+
15
+ /**
16
+ * Applies selection highlight and (where supported) handle tinting to a [TextView].
17
+ *
18
+ * Handle drawables are only tinted on API 29+ where the framework exposes getters;
19
+ * on older versions the handle theme defaults remain unchanged.
20
+ */
21
+ fun TextView.applySelectionColors(
22
+ selectionColor: Int?,
23
+ selectionHandleColor: Int?,
24
+ ) {
25
+ selectionColor?.let { highlightColor = it }
26
+ selectionHandleColor?.let { applySelectionHandleTint(it) }
27
+ }
28
+
29
+ private fun TextView.applySelectionHandleTint(
30
+ @ColorInt color: Int,
31
+ ) {
32
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) return
33
+
34
+ val handles: List<Pair<HandleGetter, HandleSetter>> =
35
+ listOf(
36
+ TextView::getTextSelectHandleLeft to { tv, d -> tv.setTextSelectHandleLeft(d) },
37
+ TextView::getTextSelectHandle to { tv, d -> tv.setTextSelectHandle(d) },
38
+ TextView::getTextSelectHandleRight to { tv, d -> tv.setTextSelectHandleRight(d) },
39
+ )
40
+
41
+ handles.forEach { (getter, setter) ->
42
+ try {
43
+ getter(this)?.mutate()?.also { DrawableCompat.setTint(it, color) }?.let { setter(this, it) }
44
+ } catch (e: LinkageError) {
45
+ Log.w(TAG, "Selection handle tint skipped: ${e.message}")
46
+ }
47
+ }
48
+ }