@mathers101/react-native-render-rich-text 0.1.10 → 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,119 +1,119 @@
1
- package com.renderrichtext.utils.text.view
2
-
3
- import android.graphics.Color
4
- import android.os.Build
5
- import android.text.GetChars
6
- import android.text.Spannable
7
- import android.text.SpannableString
8
- import android.text.SpannableStringBuilder
9
- import android.view.textclassifier.TextClassifier
10
- import androidx.appcompat.widget.AppCompatTextView
11
- import androidx.core.view.ViewCompat
12
- import com.renderrichtext.accessibility.AccessibleTiptapTextView
13
-
14
- /**
15
- * Adopts the renderer's buffer instead of copying it: the default factory's copy is
16
- * quadratic in span count. Safe because each segment's buffer is owned by one view.
17
- */
18
- private object NoCopySpannableFactory : Spannable.Factory() {
19
- override fun newSpannable(source: CharSequence): Spannable =
20
- when (source) {
21
- is SpannableStringBuilder -> InsertionOrderedSpannable(source)
22
- is Spannable -> source
23
- else -> SpannableString(source)
24
- }
25
- }
26
-
27
- /**
28
- * Hides that [buffer] is a `SpannableStringBuilder`. Layout reads a builder's paragraph
29
- * spans in position order rather than insertion order, which paints nested list margins
30
- * outer-first and pushes nested checkboxes an indent right.
31
- *
32
- * Hiding the type has a price, and it is deliberate: every paragraph-span query from
33
- * `Layout` now goes through the builder's sorted `getSpans` instead of the unsorted fast
34
- * path the framework reserves for builders. The `layout` benchmark in the example app's
35
- * `display-benchmark` covers that cost, so it is already accounted for. Do not
36
- * "optimise" this wrapper away.
37
- */
38
- private class InsertionOrderedSpannable(
39
- private val buffer: SpannableStringBuilder,
40
- ) : Spannable,
41
- GetChars {
42
- override val length: Int get() = buffer.length
43
-
44
- override fun get(index: Int): Char = buffer[index]
45
-
46
- override fun subSequence(
47
- startIndex: Int,
48
- endIndex: Int,
49
- ): CharSequence = buffer.subSequence(startIndex, endIndex)
50
-
51
- override fun getChars(
52
- start: Int,
53
- end: Int,
54
- dest: CharArray,
55
- destoff: Int,
56
- ) = buffer.getChars(start, end, dest, destoff)
57
-
58
- override fun <T : Any?> getSpans(
59
- start: Int,
60
- end: Int,
61
- type: Class<T>,
62
- ): Array<T> = buffer.getSpans(start, end, type)
63
-
64
- override fun getSpanStart(tag: Any): Int = buffer.getSpanStart(tag)
65
-
66
- override fun getSpanEnd(tag: Any): Int = buffer.getSpanEnd(tag)
67
-
68
- override fun getSpanFlags(tag: Any): Int = buffer.getSpanFlags(tag)
69
-
70
- override fun nextSpanTransition(
71
- start: Int,
72
- limit: Int,
73
- type: Class<*>?,
74
- ): Int = buffer.nextSpanTransition(start, limit, type)
75
-
76
- override fun setSpan(
77
- what: Any,
78
- start: Int,
79
- end: Int,
80
- flags: Int,
81
- ) = buffer.setSpan(what, start, end, flags)
82
-
83
- override fun removeSpan(what: Any) = buffer.removeSpan(what)
84
-
85
- override fun toString(): String = buffer.toString()
86
- }
87
-
88
- fun AccessibleTiptapTextView.setupAsTiptapTextView() {
89
- setBackgroundColor(Color.TRANSPARENT)
90
- setSpannableFactory(NoCopySpannableFactory)
91
- includeFontPadding = false
92
- movementMethod = LinkLongPressMovementMethod.createInstance()
93
- setTextIsSelectable(true)
94
- customSelectionActionModeCallback = createSelectionActionModeCallback(this)
95
- // SmartSelectSprite crashes with "Center point is not inside any of the
96
- // rectangles!" when Layout.getSelection returns empty rects near an
97
- // ImageSpan (ReplacementSpan). NO_OP makes skipTextClassification() return
98
- // true, bypassing the entire SmartSelectSprite code path. Regular text
99
- // selection (long-press, handles, copy/paste) still works; only automatic
100
- // entity detection (phone numbers, addresses) is disabled.
101
- //
102
- // TODO: Add an Android-only `enableSmartTextSelection` prop that skips this
103
- // NO_OP override. This would let users who don't render images opt in to
104
- // entity detection. The prop should default to false and its docs should
105
- // warn that enabling it with tiptap containing images will crash.
106
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
107
- setTextClassifier(TextClassifier.NO_OP)
108
- }
109
- isVerticalScrollBarEnabled = false
110
- isHorizontalScrollBarEnabled = false
111
- ViewCompat.setAccessibilityDelegate(this, accessibilityHelper)
112
- }
113
-
114
- fun AppCompatTextView.applySelectableState(selectable: Boolean) {
115
- if (isTextSelectable == selectable) return
116
- setTextIsSelectable(selectable)
117
- movementMethod = LinkLongPressMovementMethod.createInstance()
118
- if (!selectable && !isClickable) isClickable = true
119
- }
1
+ package com.renderrichtext.utils.text.view
2
+
3
+ import android.graphics.Color
4
+ import android.os.Build
5
+ import android.text.GetChars
6
+ import android.text.Spannable
7
+ import android.text.SpannableString
8
+ import android.text.SpannableStringBuilder
9
+ import android.view.textclassifier.TextClassifier
10
+ import androidx.appcompat.widget.AppCompatTextView
11
+ import androidx.core.view.ViewCompat
12
+ import com.renderrichtext.accessibility.AccessibleTiptapTextView
13
+
14
+ /**
15
+ * Adopts the renderer's buffer instead of copying it: the default factory's copy is
16
+ * quadratic in span count. Safe because each segment's buffer is owned by one view.
17
+ */
18
+ private object NoCopySpannableFactory : Spannable.Factory() {
19
+ override fun newSpannable(source: CharSequence): Spannable =
20
+ when (source) {
21
+ is SpannableStringBuilder -> InsertionOrderedSpannable(source)
22
+ is Spannable -> source
23
+ else -> SpannableString(source)
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Hides that [buffer] is a `SpannableStringBuilder`. Layout reads a builder's paragraph
29
+ * spans in position order rather than insertion order, which paints nested list margins
30
+ * outer-first and pushes nested checkboxes an indent right.
31
+ *
32
+ * Hiding the type has a price, and it is deliberate: every paragraph-span query from
33
+ * `Layout` now goes through the builder's sorted `getSpans` instead of the unsorted fast
34
+ * path the framework reserves for builders. The `layout` benchmark in the example app's
35
+ * `display-benchmark` covers that cost, so it is already accounted for. Do not
36
+ * "optimise" this wrapper away.
37
+ */
38
+ private class InsertionOrderedSpannable(
39
+ private val buffer: SpannableStringBuilder,
40
+ ) : Spannable,
41
+ GetChars {
42
+ override val length: Int get() = buffer.length
43
+
44
+ override fun get(index: Int): Char = buffer[index]
45
+
46
+ override fun subSequence(
47
+ startIndex: Int,
48
+ endIndex: Int,
49
+ ): CharSequence = buffer.subSequence(startIndex, endIndex)
50
+
51
+ override fun getChars(
52
+ start: Int,
53
+ end: Int,
54
+ dest: CharArray,
55
+ destoff: Int,
56
+ ) = buffer.getChars(start, end, dest, destoff)
57
+
58
+ override fun <T : Any?> getSpans(
59
+ start: Int,
60
+ end: Int,
61
+ type: Class<T>,
62
+ ): Array<T> = buffer.getSpans(start, end, type)
63
+
64
+ override fun getSpanStart(tag: Any): Int = buffer.getSpanStart(tag)
65
+
66
+ override fun getSpanEnd(tag: Any): Int = buffer.getSpanEnd(tag)
67
+
68
+ override fun getSpanFlags(tag: Any): Int = buffer.getSpanFlags(tag)
69
+
70
+ override fun nextSpanTransition(
71
+ start: Int,
72
+ limit: Int,
73
+ type: Class<*>?,
74
+ ): Int = buffer.nextSpanTransition(start, limit, type)
75
+
76
+ override fun setSpan(
77
+ what: Any,
78
+ start: Int,
79
+ end: Int,
80
+ flags: Int,
81
+ ) = buffer.setSpan(what, start, end, flags)
82
+
83
+ override fun removeSpan(what: Any) = buffer.removeSpan(what)
84
+
85
+ override fun toString(): String = buffer.toString()
86
+ }
87
+
88
+ fun AccessibleTiptapTextView.setupAsTiptapTextView() {
89
+ setBackgroundColor(Color.TRANSPARENT)
90
+ setSpannableFactory(NoCopySpannableFactory)
91
+ includeFontPadding = false
92
+ movementMethod = LinkLongPressMovementMethod.createInstance()
93
+ setTextIsSelectable(true)
94
+ customSelectionActionModeCallback = createSelectionActionModeCallback(this)
95
+ // SmartSelectSprite crashes with "Center point is not inside any of the
96
+ // rectangles!" when Layout.getSelection returns empty rects near an
97
+ // ImageSpan (ReplacementSpan). NO_OP makes skipTextClassification() return
98
+ // true, bypassing the entire SmartSelectSprite code path. Regular text
99
+ // selection (long-press, handles, copy/paste) still works; only automatic
100
+ // entity detection (phone numbers, addresses) is disabled.
101
+ //
102
+ // TODO: Add an Android-only `enableSmartTextSelection` prop that skips this
103
+ // NO_OP override. This would let users who don't render images opt in to
104
+ // entity detection. The prop should default to false and its docs should
105
+ // warn that enabling it with tiptap containing images will crash.
106
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
107
+ setTextClassifier(TextClassifier.NO_OP)
108
+ }
109
+ isVerticalScrollBarEnabled = false
110
+ isHorizontalScrollBarEnabled = false
111
+ ViewCompat.setAccessibilityDelegate(this, accessibilityHelper)
112
+ }
113
+
114
+ fun AppCompatTextView.applySelectableState(selectable: Boolean) {
115
+ if (isTextSelectable == selectable) return
116
+ setTextIsSelectable(selectable)
117
+ movementMethod = LinkLongPressMovementMethod.createInstance()
118
+ if (!selectable && !isClickable) isClickable = true
119
+ }
@@ -1,217 +1,217 @@
1
- package com.renderrichtext.views
2
-
3
- import android.content.Context
4
- import android.graphics.Canvas
5
- import android.graphics.Color
6
- import android.graphics.ColorFilter
7
- import android.graphics.Paint
8
- import android.graphics.PixelFormat
9
- import android.graphics.RectF
10
- import android.graphics.Typeface
11
- import android.graphics.drawable.ColorDrawable
12
- import android.graphics.drawable.Drawable
13
- import android.graphics.drawable.GradientDrawable
14
- import android.util.TypedValue
15
- import android.view.Gravity
16
- import android.view.View
17
- import android.view.View.MeasureSpec
18
- import android.view.ViewGroup
19
- import android.widget.ImageView
20
- import android.widget.LinearLayout
21
- import android.widget.PopupWindow
22
- import android.widget.TextView
23
- import kotlin.math.roundToInt
24
-
25
- object ContextMenuPopup {
26
- private var activePopup: PopupWindow? = null
27
-
28
- fun dismiss() {
29
- activePopup?.dismiss()
30
- }
31
-
32
- enum class Icon { COPY, DOCUMENT }
33
-
34
- class Builder internal constructor() {
35
- internal val items = mutableListOf<MenuItem>()
36
-
37
- fun item(
38
- icon: Icon,
39
- label: String,
40
- onClick: () -> Unit,
41
- ) {
42
- items.add(MenuItem(icon, label, onClick))
43
- }
44
- }
45
-
46
- internal data class MenuItem(
47
- val icon: Icon,
48
- val label: String,
49
- val onClick: () -> Unit,
50
- )
51
-
52
- private var density = 1f
53
- private val Float.dp get() = (this * density).roundToInt()
54
-
55
- fun show(
56
- anchor: View,
57
- parent: View,
58
- block: Builder.() -> Unit,
59
- ) {
60
- activePopup?.dismiss()
61
-
62
- val context = anchor.context
63
- density = context.resources.displayMetrics.density
64
- val builder = Builder().apply(block)
65
- if (builder.items.isEmpty()) return
66
-
67
- val container =
68
- LinearLayout(context).apply {
69
- orientation = LinearLayout.VERTICAL
70
- elevation = 12f.dp.toFloat()
71
- setPadding(4f.dp, 12f.dp, 4f.dp, 12f.dp)
72
- background =
73
- GradientDrawable().apply {
74
- setColor(Color.WHITE)
75
- cornerRadius = 14f.dp.toFloat()
76
- }
77
- }
78
-
79
- builder.items.forEachIndexed { index, item ->
80
- if (index > 0) container.addView(createDivider(context))
81
- container.addView(createMenuItemView(context, item))
82
- }
83
-
84
- val popup =
85
- PopupWindow(
86
- container,
87
- ViewGroup.LayoutParams.WRAP_CONTENT,
88
- ViewGroup.LayoutParams.WRAP_CONTENT,
89
- true,
90
- ).apply {
91
- elevation = 24f.dp.toFloat()
92
- isOutsideTouchable = true
93
- setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
94
- setOnDismissListener {
95
- activePopup = null
96
- }
97
- }
98
-
99
- container.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
100
-
101
- val location = IntArray(2).also { anchor.getLocationOnScreen(it) }
102
- val centerX = location[0] + anchor.width / 2
103
- val topY = location[1]
104
-
105
- val screenW = context.resources.displayMetrics.widthPixels
106
- val margin = 8f.dp
107
-
108
- val x =
109
- (centerX - container.measuredWidth / 2)
110
- .coerceIn(margin, screenW - container.measuredWidth - margin)
111
- val y =
112
- (topY - container.measuredHeight - margin)
113
- .coerceAtLeast(margin)
114
-
115
- activePopup = popup
116
- popup.showAtLocation(parent, Gravity.NO_GRAVITY, x, y)
117
- }
118
-
119
- private fun createMenuItemView(
120
- context: Context,
121
- item: MenuItem,
122
- ) = LinearLayout(context).apply {
123
- orientation = LinearLayout.HORIZONTAL
124
- gravity = Gravity.CENTER_VERTICAL
125
- setPadding(16f.dp, 0, 16f.dp, 0)
126
- minimumHeight = 48f.dp
127
- isClickable = true
128
- isFocusable = true
129
-
130
- val outValue = TypedValue()
131
- context.theme.resolveAttribute(android.R.attr.selectableItemBackground, outValue, true)
132
- foreground = context.getDrawable(outValue.resourceId)
133
-
134
- addView(
135
- ImageView(context).apply {
136
- setImageDrawable(createIconDrawable(item.icon))
137
- setColorFilter(Color.parseColor("#333333"))
138
- },
139
- LinearLayout.LayoutParams(20f.dp, 20f.dp),
140
- )
141
-
142
- addView(
143
- TextView(context).apply {
144
- text = item.label
145
- textSize = 16f
146
- setTextColor(Color.parseColor("#1C1C1E"))
147
- typeface = Typeface.create("sans-serif-medium", Typeface.NORMAL)
148
- },
149
- LinearLayout
150
- .LayoutParams(
151
- ViewGroup.LayoutParams.WRAP_CONTENT,
152
- ViewGroup.LayoutParams.WRAP_CONTENT,
153
- ).apply { marginStart = 12f.dp },
154
- )
155
-
156
- setOnClickListener {
157
- item.onClick()
158
- dismiss()
159
- }
160
- }
161
-
162
- private fun createDivider(context: Context) =
163
- View(context).apply {
164
- setBackgroundColor(Color.parseColor("#E5E5EA"))
165
- layoutParams =
166
- LinearLayout
167
- .LayoutParams(
168
- ViewGroup.LayoutParams.MATCH_PARENT,
169
- 1f.dp.coerceAtLeast(1),
170
- ).apply {
171
- setMargins(16f.dp, 0, 16f.dp, 0)
172
- }
173
- }
174
-
175
- private fun createIconDrawable(icon: Icon): Drawable =
176
- object : Drawable() {
177
- private val paint =
178
- Paint(Paint.ANTI_ALIAS_FLAG).apply {
179
- style = Paint.Style.STROKE
180
- strokeWidth = 1.5f * density
181
- strokeJoin = Paint.Join.ROUND
182
- strokeCap = Paint.Cap.ROUND
183
- color = Color.parseColor("#333333")
184
- }
185
-
186
- private val copyGlyph = CopyGlyph()
187
-
188
- // COPY mirrors SF Symbol doc.on.doc, DOCUMENT mirrors doc.text; the copy
189
- // glyph is shared with the header button in CodeBlockContainerView.
190
- override fun draw(canvas: Canvas) {
191
- val u = bounds.width() / 24f
192
- if (icon == Icon.COPY) {
193
- copyGlyph.draw(canvas, bounds.width().toFloat(), paint)
194
- } else {
195
- canvas.drawRoundRect(RectF(5 * u, 3 * u, 19 * u, 21 * u), 2.5f * u, 2.5f * u, paint)
196
- canvas.drawLine(8.5f * u, 9 * u, 15.5f * u, 9 * u, paint)
197
- canvas.drawLine(8.5f * u, 12.5f * u, 15.5f * u, 12.5f * u, paint)
198
- canvas.drawLine(8.5f * u, 16 * u, 13 * u, 16 * u, paint)
199
- }
200
- }
201
-
202
- override fun getIntrinsicWidth() = 24f.dp
203
-
204
- override fun getIntrinsicHeight() = 24f.dp
205
-
206
- override fun setAlpha(alpha: Int) {
207
- paint.alpha = alpha
208
- }
209
-
210
- override fun setColorFilter(colorFilter: ColorFilter?) {
211
- paint.colorFilter = colorFilter
212
- }
213
-
214
- @Deprecated("Deprecated in Java")
215
- override fun getOpacity() = PixelFormat.TRANSLUCENT
216
- }
217
- }
1
+ package com.renderrichtext.views
2
+
3
+ import android.content.Context
4
+ import android.graphics.Canvas
5
+ import android.graphics.Color
6
+ import android.graphics.ColorFilter
7
+ import android.graphics.Paint
8
+ import android.graphics.PixelFormat
9
+ import android.graphics.RectF
10
+ import android.graphics.Typeface
11
+ import android.graphics.drawable.ColorDrawable
12
+ import android.graphics.drawable.Drawable
13
+ import android.graphics.drawable.GradientDrawable
14
+ import android.util.TypedValue
15
+ import android.view.Gravity
16
+ import android.view.View
17
+ import android.view.View.MeasureSpec
18
+ import android.view.ViewGroup
19
+ import android.widget.ImageView
20
+ import android.widget.LinearLayout
21
+ import android.widget.PopupWindow
22
+ import android.widget.TextView
23
+ import kotlin.math.roundToInt
24
+
25
+ object ContextMenuPopup {
26
+ private var activePopup: PopupWindow? = null
27
+
28
+ fun dismiss() {
29
+ activePopup?.dismiss()
30
+ }
31
+
32
+ enum class Icon { COPY, DOCUMENT }
33
+
34
+ class Builder internal constructor() {
35
+ internal val items = mutableListOf<MenuItem>()
36
+
37
+ fun item(
38
+ icon: Icon,
39
+ label: String,
40
+ onClick: () -> Unit,
41
+ ) {
42
+ items.add(MenuItem(icon, label, onClick))
43
+ }
44
+ }
45
+
46
+ internal data class MenuItem(
47
+ val icon: Icon,
48
+ val label: String,
49
+ val onClick: () -> Unit,
50
+ )
51
+
52
+ private var density = 1f
53
+ private val Float.dp get() = (this * density).roundToInt()
54
+
55
+ fun show(
56
+ anchor: View,
57
+ parent: View,
58
+ block: Builder.() -> Unit,
59
+ ) {
60
+ activePopup?.dismiss()
61
+
62
+ val context = anchor.context
63
+ density = context.resources.displayMetrics.density
64
+ val builder = Builder().apply(block)
65
+ if (builder.items.isEmpty()) return
66
+
67
+ val container =
68
+ LinearLayout(context).apply {
69
+ orientation = LinearLayout.VERTICAL
70
+ elevation = 12f.dp.toFloat()
71
+ setPadding(4f.dp, 12f.dp, 4f.dp, 12f.dp)
72
+ background =
73
+ GradientDrawable().apply {
74
+ setColor(Color.WHITE)
75
+ cornerRadius = 14f.dp.toFloat()
76
+ }
77
+ }
78
+
79
+ builder.items.forEachIndexed { index, item ->
80
+ if (index > 0) container.addView(createDivider(context))
81
+ container.addView(createMenuItemView(context, item))
82
+ }
83
+
84
+ val popup =
85
+ PopupWindow(
86
+ container,
87
+ ViewGroup.LayoutParams.WRAP_CONTENT,
88
+ ViewGroup.LayoutParams.WRAP_CONTENT,
89
+ true,
90
+ ).apply {
91
+ elevation = 24f.dp.toFloat()
92
+ isOutsideTouchable = true
93
+ setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
94
+ setOnDismissListener {
95
+ activePopup = null
96
+ }
97
+ }
98
+
99
+ container.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
100
+
101
+ val location = IntArray(2).also { anchor.getLocationOnScreen(it) }
102
+ val centerX = location[0] + anchor.width / 2
103
+ val topY = location[1]
104
+
105
+ val screenW = context.resources.displayMetrics.widthPixels
106
+ val margin = 8f.dp
107
+
108
+ val x =
109
+ (centerX - container.measuredWidth / 2)
110
+ .coerceIn(margin, screenW - container.measuredWidth - margin)
111
+ val y =
112
+ (topY - container.measuredHeight - margin)
113
+ .coerceAtLeast(margin)
114
+
115
+ activePopup = popup
116
+ popup.showAtLocation(parent, Gravity.NO_GRAVITY, x, y)
117
+ }
118
+
119
+ private fun createMenuItemView(
120
+ context: Context,
121
+ item: MenuItem,
122
+ ) = LinearLayout(context).apply {
123
+ orientation = LinearLayout.HORIZONTAL
124
+ gravity = Gravity.CENTER_VERTICAL
125
+ setPadding(16f.dp, 0, 16f.dp, 0)
126
+ minimumHeight = 48f.dp
127
+ isClickable = true
128
+ isFocusable = true
129
+
130
+ val outValue = TypedValue()
131
+ context.theme.resolveAttribute(android.R.attr.selectableItemBackground, outValue, true)
132
+ foreground = context.getDrawable(outValue.resourceId)
133
+
134
+ addView(
135
+ ImageView(context).apply {
136
+ setImageDrawable(createIconDrawable(item.icon))
137
+ setColorFilter(Color.parseColor("#333333"))
138
+ },
139
+ LinearLayout.LayoutParams(20f.dp, 20f.dp),
140
+ )
141
+
142
+ addView(
143
+ TextView(context).apply {
144
+ text = item.label
145
+ textSize = 16f
146
+ setTextColor(Color.parseColor("#1C1C1E"))
147
+ typeface = Typeface.create("sans-serif-medium", Typeface.NORMAL)
148
+ },
149
+ LinearLayout
150
+ .LayoutParams(
151
+ ViewGroup.LayoutParams.WRAP_CONTENT,
152
+ ViewGroup.LayoutParams.WRAP_CONTENT,
153
+ ).apply { marginStart = 12f.dp },
154
+ )
155
+
156
+ setOnClickListener {
157
+ item.onClick()
158
+ dismiss()
159
+ }
160
+ }
161
+
162
+ private fun createDivider(context: Context) =
163
+ View(context).apply {
164
+ setBackgroundColor(Color.parseColor("#E5E5EA"))
165
+ layoutParams =
166
+ LinearLayout
167
+ .LayoutParams(
168
+ ViewGroup.LayoutParams.MATCH_PARENT,
169
+ 1f.dp.coerceAtLeast(1),
170
+ ).apply {
171
+ setMargins(16f.dp, 0, 16f.dp, 0)
172
+ }
173
+ }
174
+
175
+ private fun createIconDrawable(icon: Icon): Drawable =
176
+ object : Drawable() {
177
+ private val paint =
178
+ Paint(Paint.ANTI_ALIAS_FLAG).apply {
179
+ style = Paint.Style.STROKE
180
+ strokeWidth = 1.5f * density
181
+ strokeJoin = Paint.Join.ROUND
182
+ strokeCap = Paint.Cap.ROUND
183
+ color = Color.parseColor("#333333")
184
+ }
185
+
186
+ private val copyGlyph = CopyGlyph()
187
+
188
+ // COPY mirrors SF Symbol doc.on.doc, DOCUMENT mirrors doc.text; the copy
189
+ // glyph is shared with the header button in CodeBlockContainerView.
190
+ override fun draw(canvas: Canvas) {
191
+ val u = bounds.width() / 24f
192
+ if (icon == Icon.COPY) {
193
+ copyGlyph.draw(canvas, bounds.width().toFloat(), paint)
194
+ } else {
195
+ canvas.drawRoundRect(RectF(5 * u, 3 * u, 19 * u, 21 * u), 2.5f * u, 2.5f * u, paint)
196
+ canvas.drawLine(8.5f * u, 9 * u, 15.5f * u, 9 * u, paint)
197
+ canvas.drawLine(8.5f * u, 12.5f * u, 15.5f * u, 12.5f * u, paint)
198
+ canvas.drawLine(8.5f * u, 16 * u, 13 * u, 16 * u, paint)
199
+ }
200
+ }
201
+
202
+ override fun getIntrinsicWidth() = 24f.dp
203
+
204
+ override fun getIntrinsicHeight() = 24f.dp
205
+
206
+ override fun setAlpha(alpha: Int) {
207
+ paint.alpha = alpha
208
+ }
209
+
210
+ override fun setColorFilter(colorFilter: ColorFilter?) {
211
+ paint.colorFilter = colorFilter
212
+ }
213
+
214
+ @Deprecated("Deprecated in Java")
215
+ override fun getOpacity() = PixelFormat.TRANSLUCENT
216
+ }
217
+ }