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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +140 -3
  3. package/ReactNativeRenderRichText.podspec +23 -0
  4. package/android/build.gradle +86 -0
  5. package/android/consumer-rules.pro +3 -0
  6. package/android/src/main/AndroidManifest.xml +2 -0
  7. package/android/src/main/cpp/jni-adapter.cpp +191 -0
  8. package/android/src/main/java/com/renderrichtext/EnrichedTiptapText.kt +673 -0
  9. package/android/src/main/java/com/renderrichtext/EnrichedTiptapTextLayoutManager.kt +24 -0
  10. package/android/src/main/java/com/renderrichtext/EnrichedTiptapTextManager.kt +405 -0
  11. package/android/src/main/java/com/renderrichtext/EnrichedTiptapTextPackage.kt +13 -0
  12. package/android/src/main/java/com/renderrichtext/MeasurementStore.kt +644 -0
  13. package/android/src/main/java/com/renderrichtext/accessibility/AccessibilityLabels.kt +17 -0
  14. package/android/src/main/java/com/renderrichtext/accessibility/AccessibleTiptapTextView.kt +112 -0
  15. package/android/src/main/java/com/renderrichtext/accessibility/TiptapAccessibilityHelper.kt +576 -0
  16. package/android/src/main/java/com/renderrichtext/events/CodeBlockPressEvent.kt +24 -0
  17. package/android/src/main/java/com/renderrichtext/events/ContextMenuItemPressEvent.kt +28 -0
  18. package/android/src/main/java/com/renderrichtext/events/CopyPressEvent.kt +24 -0
  19. package/android/src/main/java/com/renderrichtext/events/FactoidPressEvent.kt +23 -0
  20. package/android/src/main/java/com/renderrichtext/events/ImagePressEvent.kt +25 -0
  21. package/android/src/main/java/com/renderrichtext/events/LatexErrorEvent.kt +29 -0
  22. package/android/src/main/java/com/renderrichtext/events/LinkLongPressEvent.kt +23 -0
  23. package/android/src/main/java/com/renderrichtext/events/LinkPressEvent.kt +23 -0
  24. package/android/src/main/java/com/renderrichtext/events/MentionLongPressEvent.kt +25 -0
  25. package/android/src/main/java/com/renderrichtext/events/MentionPressEvent.kt +25 -0
  26. package/android/src/main/java/com/renderrichtext/events/TaskListItemPressEvent.kt +26 -0
  27. package/android/src/main/java/com/renderrichtext/math/LatexErrorReporter.kt +9 -0
  28. package/android/src/main/java/com/renderrichtext/parser/Parser.kt +59 -0
  29. package/android/src/main/java/com/renderrichtext/parser/TextLinkMatching.kt +35 -0
  30. package/android/src/main/java/com/renderrichtext/parser/TiptapASTNode.kt +69 -0
  31. package/android/src/main/java/com/renderrichtext/renderer/BaselineShiftRenderer.kt +45 -0
  32. package/android/src/main/java/com/renderrichtext/renderer/BlankLineRenderer.kt +39 -0
  33. package/android/src/main/java/com/renderrichtext/renderer/BlockStyleContext.kt +181 -0
  34. package/android/src/main/java/com/renderrichtext/renderer/BlockquoteRenderer.kt +243 -0
  35. package/android/src/main/java/com/renderrichtext/renderer/BlockquoteTextRenderer.kt +56 -0
  36. package/android/src/main/java/com/renderrichtext/renderer/CodeBlockRenderer.kt +135 -0
  37. package/android/src/main/java/com/renderrichtext/renderer/CodeRenderer.kt +37 -0
  38. package/android/src/main/java/com/renderrichtext/renderer/EmphasisRenderer.kt +28 -0
  39. package/android/src/main/java/com/renderrichtext/renderer/FactoidRenderer.kt +97 -0
  40. package/android/src/main/java/com/renderrichtext/renderer/HeadingRenderer.kt +81 -0
  41. package/android/src/main/java/com/renderrichtext/renderer/HighlightRenderer.kt +26 -0
  42. package/android/src/main/java/com/renderrichtext/renderer/LineBreakRenderer.kt +17 -0
  43. package/android/src/main/java/com/renderrichtext/renderer/LinkRenderer.kt +90 -0
  44. package/android/src/main/java/com/renderrichtext/renderer/ListContextManager.kt +109 -0
  45. package/android/src/main/java/com/renderrichtext/renderer/ListItemRenderer.kt +211 -0
  46. package/android/src/main/java/com/renderrichtext/renderer/ListRenderer.kt +133 -0
  47. package/android/src/main/java/com/renderrichtext/renderer/MentionRenderer.kt +85 -0
  48. package/android/src/main/java/com/renderrichtext/renderer/NodeRenderer.kt +207 -0
  49. package/android/src/main/java/com/renderrichtext/renderer/ParagraphRenderer.kt +91 -0
  50. package/android/src/main/java/com/renderrichtext/renderer/Renderer.kt +148 -0
  51. package/android/src/main/java/com/renderrichtext/renderer/SoftBreakRenderer.kt +17 -0
  52. package/android/src/main/java/com/renderrichtext/renderer/SpanStyleCache.kt +143 -0
  53. package/android/src/main/java/com/renderrichtext/renderer/StrikethroughRenderer.kt +28 -0
  54. package/android/src/main/java/com/renderrichtext/renderer/StrongRenderer.kt +28 -0
  55. package/android/src/main/java/com/renderrichtext/renderer/TextRenderer.kt +31 -0
  56. package/android/src/main/java/com/renderrichtext/renderer/ThematicBreakRenderer.kt +46 -0
  57. package/android/src/main/java/com/renderrichtext/renderer/UnderlineRenderer.kt +28 -0
  58. package/android/src/main/java/com/renderrichtext/spans/BaseListSpan.kt +164 -0
  59. package/android/src/main/java/com/renderrichtext/spans/BaselineShiftSpan.kt +27 -0
  60. package/android/src/main/java/com/renderrichtext/spans/BlockquoteSpan.kt +302 -0
  61. package/android/src/main/java/com/renderrichtext/spans/CodeBackgroundSpan.kt +205 -0
  62. package/android/src/main/java/com/renderrichtext/spans/CodeBlockSpan.kt +216 -0
  63. package/android/src/main/java/com/renderrichtext/spans/CodeSpan.kt +32 -0
  64. package/android/src/main/java/com/renderrichtext/spans/EmphasisSpan.kt +42 -0
  65. package/android/src/main/java/com/renderrichtext/spans/FactoidBackgroundSpan.kt +265 -0
  66. package/android/src/main/java/com/renderrichtext/spans/FactoidPaddingSpan.kt +258 -0
  67. package/android/src/main/java/com/renderrichtext/spans/FactoidSpan.kt +32 -0
  68. package/android/src/main/java/com/renderrichtext/spans/FadeInSpan.kt +29 -0
  69. package/android/src/main/java/com/renderrichtext/spans/HeadingSpan.kt +38 -0
  70. package/android/src/main/java/com/renderrichtext/spans/HighlightSpan.kt +80 -0
  71. package/android/src/main/java/com/renderrichtext/spans/ImageSpan.kt +481 -0
  72. package/android/src/main/java/com/renderrichtext/spans/InlineBackgroundGeometry.kt +42 -0
  73. package/android/src/main/java/com/renderrichtext/spans/LineHeightSpan.kt +39 -0
  74. package/android/src/main/java/com/renderrichtext/spans/LinkPillIconCache.kt +154 -0
  75. package/android/src/main/java/com/renderrichtext/spans/LinkPillSpan.kt +381 -0
  76. package/android/src/main/java/com/renderrichtext/spans/LinkSpan.kt +68 -0
  77. package/android/src/main/java/com/renderrichtext/spans/ListItemSpacingSpan.kt +33 -0
  78. package/android/src/main/java/com/renderrichtext/spans/ListMarkerAnchorSpan.kt +38 -0
  79. package/android/src/main/java/com/renderrichtext/spans/MarginBottomSpan.kt +76 -0
  80. package/android/src/main/java/com/renderrichtext/spans/MentionChipSpan.kt +132 -0
  81. package/android/src/main/java/com/renderrichtext/spans/MentionSpan.kt +46 -0
  82. package/android/src/main/java/com/renderrichtext/spans/OrderedListSpan.kt +127 -0
  83. package/android/src/main/java/com/renderrichtext/spans/SpoilerSpan.kt +33 -0
  84. package/android/src/main/java/com/renderrichtext/spans/StrikethroughSpan.kt +12 -0
  85. package/android/src/main/java/com/renderrichtext/spans/StrongSpan.kt +39 -0
  86. package/android/src/main/java/com/renderrichtext/spans/TaskListSpan.kt +143 -0
  87. package/android/src/main/java/com/renderrichtext/spans/TextSpan.kt +26 -0
  88. package/android/src/main/java/com/renderrichtext/spans/ThematicBreakSpan.kt +69 -0
  89. package/android/src/main/java/com/renderrichtext/spans/UnorderedListSpan.kt +96 -0
  90. package/android/src/main/java/com/renderrichtext/spoiler/SpoilerStubs.kt +46 -0
  91. package/android/src/main/java/com/renderrichtext/styles/BaseBlockStyle.kt +11 -0
  92. package/android/src/main/java/com/renderrichtext/styles/BlockquoteStyle.kt +83 -0
  93. package/android/src/main/java/com/renderrichtext/styles/CodeBlockStyle.kt +80 -0
  94. package/android/src/main/java/com/renderrichtext/styles/CodeStyle.kt +26 -0
  95. package/android/src/main/java/com/renderrichtext/styles/EmphasisStyle.kt +21 -0
  96. package/android/src/main/java/com/renderrichtext/styles/FactoidStyle.kt +21 -0
  97. package/android/src/main/java/com/renderrichtext/styles/HeadingStyle.kt +33 -0
  98. package/android/src/main/java/com/renderrichtext/styles/HighlightStyle.kt +19 -0
  99. package/android/src/main/java/com/renderrichtext/styles/ImageStyle.kt +29 -0
  100. package/android/src/main/java/com/renderrichtext/styles/InlineImageStyle.kt +17 -0
  101. package/android/src/main/java/com/renderrichtext/styles/InlineMathStyle.kt +17 -0
  102. package/android/src/main/java/com/renderrichtext/styles/LinkPillContent.kt +36 -0
  103. package/android/src/main/java/com/renderrichtext/styles/LinkPillStyle.kt +44 -0
  104. package/android/src/main/java/com/renderrichtext/styles/LinkStyle.kt +23 -0
  105. package/android/src/main/java/com/renderrichtext/styles/LinkVariantEntry.kt +34 -0
  106. package/android/src/main/java/com/renderrichtext/styles/ListStyle.kt +65 -0
  107. package/android/src/main/java/com/renderrichtext/styles/MathStyle.kt +29 -0
  108. package/android/src/main/java/com/renderrichtext/styles/MentionStyle.kt +19 -0
  109. package/android/src/main/java/com/renderrichtext/styles/ParagraphStyle.kt +33 -0
  110. package/android/src/main/java/com/renderrichtext/styles/SpoilerStyle.kt +27 -0
  111. package/android/src/main/java/com/renderrichtext/styles/StrikethroughStyle.kt +17 -0
  112. package/android/src/main/java/com/renderrichtext/styles/StrongStyle.kt +21 -0
  113. package/android/src/main/java/com/renderrichtext/styles/StyleConfig.kt +411 -0
  114. package/android/src/main/java/com/renderrichtext/styles/StyleParser.kt +92 -0
  115. package/android/src/main/java/com/renderrichtext/styles/SubscriptStyle.kt +16 -0
  116. package/android/src/main/java/com/renderrichtext/styles/SuperscriptStyle.kt +16 -0
  117. package/android/src/main/java/com/renderrichtext/styles/TableStyle.kt +75 -0
  118. package/android/src/main/java/com/renderrichtext/styles/TaskListStyle.kt +29 -0
  119. package/android/src/main/java/com/renderrichtext/styles/TextAlignment.kt +32 -0
  120. package/android/src/main/java/com/renderrichtext/styles/ThematicBreakStyle.kt +23 -0
  121. package/android/src/main/java/com/renderrichtext/styles/UnderlineStyle.kt +17 -0
  122. package/android/src/main/java/com/renderrichtext/styles/VideoStyle.kt +31 -0
  123. package/android/src/main/java/com/renderrichtext/utils/common/BorderStyleUtils.kt +86 -0
  124. package/android/src/main/java/com/renderrichtext/utils/common/BreakStrategyUtils.kt +32 -0
  125. package/android/src/main/java/com/renderrichtext/utils/common/CodeBlockHighlighter.kt +36 -0
  126. package/android/src/main/java/com/renderrichtext/utils/common/CodeBlockNode.kt +42 -0
  127. package/android/src/main/java/com/renderrichtext/utils/common/EllipsizeUtils.kt +27 -0
  128. package/android/src/main/java/com/renderrichtext/utils/common/EnrichedTiptapAncestorUtils.kt +10 -0
  129. package/android/src/main/java/com/renderrichtext/utils/common/FeatureFlags.kt +9 -0
  130. package/android/src/main/java/com/renderrichtext/utils/common/LinkRecognitionProps.kt +31 -0
  131. package/android/src/main/java/com/renderrichtext/utils/common/LinkRegexConfig.kt +56 -0
  132. package/android/src/main/java/com/renderrichtext/utils/common/MotionPreferences.kt +18 -0
  133. package/android/src/main/java/com/renderrichtext/utils/common/ReadableMapExtensions.kt +28 -0
  134. package/android/src/main/java/com/renderrichtext/utils/common/TiptapViewManagerUtils.kt +242 -0
  135. package/android/src/main/java/com/renderrichtext/utils/common/layout/RTLUtils.kt +6 -0
  136. package/android/src/main/java/com/renderrichtext/utils/common/serialization/TiptapASTSerializer.kt +368 -0
  137. package/android/src/main/java/com/renderrichtext/utils/text/ImageCache.kt +88 -0
  138. package/android/src/main/java/com/renderrichtext/utils/text/ImageDownloader.kt +203 -0
  139. package/android/src/main/java/com/renderrichtext/utils/text/LocalImageLoader.kt +167 -0
  140. package/android/src/main/java/com/renderrichtext/utils/text/TailFadeInAnimator.kt +84 -0
  141. package/android/src/main/java/com/renderrichtext/utils/text/conversion/HTMLGenerator.kt +1105 -0
  142. package/android/src/main/java/com/renderrichtext/utils/text/conversion/TiptapExtractor.kt +423 -0
  143. package/android/src/main/java/com/renderrichtext/utils/text/extensions/ParagraphUtils.kt +9 -0
  144. package/android/src/main/java/com/renderrichtext/utils/text/extensions/SpannableExtensions.kt +9 -0
  145. package/android/src/main/java/com/renderrichtext/utils/text/extensions/TextPaintExtensions.kt +76 -0
  146. package/android/src/main/java/com/renderrichtext/utils/text/interaction/CheckboxTouchHelper.kt +61 -0
  147. package/android/src/main/java/com/renderrichtext/utils/text/interaction/TaskListTapUtils.kt +286 -0
  148. package/android/src/main/java/com/renderrichtext/utils/text/span/ApplyLineHeight.kt +39 -0
  149. package/android/src/main/java/com/renderrichtext/utils/text/span/BlockSpacing.kt +142 -0
  150. package/android/src/main/java/com/renderrichtext/utils/text/span/SpanFlags.kt +43 -0
  151. package/android/src/main/java/com/renderrichtext/utils/text/span/WidthAwareSpans.kt +30 -0
  152. package/android/src/main/java/com/renderrichtext/utils/text/view/CodeBlockPressHost.kt +15 -0
  153. package/android/src/main/java/com/renderrichtext/utils/text/view/ImagePressHost.kt +19 -0
  154. package/android/src/main/java/com/renderrichtext/utils/text/view/LinkEvents.kt +88 -0
  155. package/android/src/main/java/com/renderrichtext/utils/text/view/LinkLongPressMovementMethod.kt +449 -0
  156. package/android/src/main/java/com/renderrichtext/utils/text/view/SelectionActionMode.kt +235 -0
  157. package/android/src/main/java/com/renderrichtext/utils/text/view/TextSelectionColors.kt +48 -0
  158. package/android/src/main/java/com/renderrichtext/utils/text/view/TextViewSetup.kt +119 -0
  159. package/android/src/main/java/com/renderrichtext/views/ContextMenuPopup.kt +217 -0
  160. package/android/src/main/java/com/renderrichtext/views/CopyGlyph.kt +101 -0
  161. package/android/src/main/java/com/renderrichtext/views/WrapGlyph.kt +40 -0
  162. package/android/src/main/jni/CMakeLists.txt +52 -0
  163. package/android/src/main/jni/react/renderer/components/RichTextSpec/ComponentDescriptors.h +30 -0
  164. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextComponentDescriptor.h +29 -0
  165. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextMeasurementManager.cpp +45 -0
  166. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextMeasurementManager.h +21 -0
  167. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextShadowNode.cpp +38 -0
  168. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextShadowNode.h +53 -0
  169. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextState.cpp +9 -0
  170. package/android/src/main/jni/react/renderer/components/RichTextSpec/TiptapTextState.h +24 -0
  171. package/android/src/main/jni/react/renderer/components/RichTextSpec/conversions.h +40 -0
  172. package/cpp/parser/TiptapASTNode.hpp +68 -0
  173. package/cpp/parser/TiptapParser.cpp +233 -0
  174. package/cpp/parser/TiptapParser.hpp +13 -0
  175. package/cpp/vendor/nlohmann/json.hpp +24765 -0
  176. package/ios/EnrichedTiptapText.h +27 -0
  177. package/ios/EnrichedTiptapText.mm +1222 -0
  178. package/ios/attachments/ENRMImageAttachment.h +51 -0
  179. package/ios/attachments/ENRMImageAttachment.m +398 -0
  180. package/ios/attachments/ENRMLinkPillAttachment.h +47 -0
  181. package/ios/attachments/ENRMLinkPillAttachment.m +324 -0
  182. package/ios/attachments/ENRMLinkPillIconCache.h +28 -0
  183. package/ios/attachments/ENRMLinkPillIconCache.m +181 -0
  184. package/ios/attachments/ENRMLinkPillText.h +27 -0
  185. package/ios/attachments/ENRMLinkPillText.m +118 -0
  186. package/ios/attachments/ENRMMathInlineAttachment.h +7 -0
  187. package/ios/attachments/ENRMMathInlineAttachment.m +4 -0
  188. package/ios/attachments/ThematicBreakAttachment.h +15 -0
  189. package/ios/attachments/ThematicBreakAttachment.m +33 -0
  190. package/ios/internals/ENRMViewFreeMeasurement.h +208 -0
  191. package/ios/internals/EnrichedTiptapTextComponentDescriptor.h +19 -0
  192. package/ios/internals/EnrichedTiptapTextShadowNode.h +43 -0
  193. package/ios/internals/EnrichedTiptapTextShadowNode.mm +69 -0
  194. package/ios/internals/EnrichedTiptapTextState.h +24 -0
  195. package/ios/internals/MeasurementCache.h +308 -0
  196. package/ios/internals/ShadowMeasurementUtils.h +145 -0
  197. package/ios/parser/ENRMTextLinkAttributes.h +7 -0
  198. package/ios/parser/ENRMTiptapParser.h +33 -0
  199. package/ios/parser/ENRMTiptapParser.mm +73 -0
  200. package/ios/parser/TiptapASTNode.h +57 -0
  201. package/ios/parser/TiptapASTNode.m +52 -0
  202. package/ios/parser/TiptapParserBridge.mm +179 -0
  203. package/ios/renderer/AttributedRenderer.h +23 -0
  204. package/ios/renderer/AttributedRenderer.m +229 -0
  205. package/ios/renderer/BaseRenderer.h +33 -0
  206. package/ios/renderer/BaseRenderer.m +46 -0
  207. package/ios/renderer/BaselineShiftTextAttributes.h +10 -0
  208. package/ios/renderer/BaselineShiftTextAttributes.m +26 -0
  209. package/ios/renderer/BlankLineRenderer.h +4 -0
  210. package/ios/renderer/BlankLineRenderer.m +51 -0
  211. package/ios/renderer/BlockquoteRenderer.h +6 -0
  212. package/ios/renderer/BlockquoteRenderer.m +258 -0
  213. package/ios/renderer/CodeBlockRenderer.h +9 -0
  214. package/ios/renderer/CodeBlockRenderer.m +99 -0
  215. package/ios/renderer/CodeRenderer.h +9 -0
  216. package/ios/renderer/CodeRenderer.m +69 -0
  217. package/ios/renderer/ENRMBlockquoteTextRenderer.h +25 -0
  218. package/ios/renderer/ENRMBlockquoteTextRenderer.m +48 -0
  219. package/ios/renderer/EmphasisRenderer.h +5 -0
  220. package/ios/renderer/EmphasisRenderer.m +100 -0
  221. package/ios/renderer/FactoidRenderer.h +9 -0
  222. package/ios/renderer/FactoidRenderer.m +130 -0
  223. package/ios/renderer/HeadingRenderer.h +6 -0
  224. package/ios/renderer/HeadingRenderer.m +103 -0
  225. package/ios/renderer/HighlightRenderer.h +7 -0
  226. package/ios/renderer/HighlightRenderer.m +33 -0
  227. package/ios/renderer/LinkRenderer.h +6 -0
  228. package/ios/renderer/LinkRenderer.m +158 -0
  229. package/ios/renderer/ListItemRenderer.h +24 -0
  230. package/ios/renderer/ListItemRenderer.m +283 -0
  231. package/ios/renderer/ListRenderer.h +13 -0
  232. package/ios/renderer/ListRenderer.m +126 -0
  233. package/ios/renderer/MentionRenderer.h +9 -0
  234. package/ios/renderer/MentionRenderer.m +96 -0
  235. package/ios/renderer/NodeRenderer.h +8 -0
  236. package/ios/renderer/ParagraphRenderer.h +6 -0
  237. package/ios/renderer/ParagraphRenderer.m +85 -0
  238. package/ios/renderer/RenderContext.h +145 -0
  239. package/ios/renderer/RenderContext.m +403 -0
  240. package/ios/renderer/RendererFactory.h +12 -0
  241. package/ios/renderer/RendererFactory.m +158 -0
  242. package/ios/renderer/StrikethroughRenderer.h +5 -0
  243. package/ios/renderer/StrikethroughRenderer.m +30 -0
  244. package/ios/renderer/StrongRenderer.h +5 -0
  245. package/ios/renderer/StrongRenderer.m +88 -0
  246. package/ios/renderer/TextRenderer.h +6 -0
  247. package/ios/renderer/TextRenderer.m +18 -0
  248. package/ios/renderer/ThematicBreakRenderer.h +4 -0
  249. package/ios/renderer/ThematicBreakRenderer.m +42 -0
  250. package/ios/renderer/UnderlineRenderer.h +4 -0
  251. package/ios/renderer/UnderlineRenderer.m +41 -0
  252. package/ios/styles/ENRMFontSlot.h +12 -0
  253. package/ios/styles/ENRMFontSlot.m +24 -0
  254. package/ios/styles/StyleConfig.h +488 -0
  255. package/ios/styles/StyleConfig.mm +2820 -0
  256. package/ios/utils/AccessibilityInfo.h +35 -0
  257. package/ios/utils/AccessibilityInfo.m +24 -0
  258. package/ios/utils/BlockquoteBorder.h +26 -0
  259. package/ios/utils/BlockquoteBorder.m +294 -0
  260. package/ios/utils/CodeBackground.h +19 -0
  261. package/ios/utils/CodeBackground.m +197 -0
  262. package/ios/utils/CodeBlockBackground.h +17 -0
  263. package/ios/utils/CodeBlockBackground.m +103 -0
  264. package/ios/utils/ContextMenuUtils.h +76 -0
  265. package/ios/utils/ContextMenuUtils.mm +75 -0
  266. package/ios/utils/ENRMAccessibilityLabels.h +40 -0
  267. package/ios/utils/ENRMAccessibilityLabels.m +5 -0
  268. package/ios/utils/ENRMAsyncRenderCoordinator.h +24 -0
  269. package/ios/utils/ENRMAsyncRenderCoordinator.m +37 -0
  270. package/ios/utils/ENRMAtomicSize.h +65 -0
  271. package/ios/utils/ENRMCodeBlockContent.h +37 -0
  272. package/ios/utils/ENRMCodeBlockContent.mm +89 -0
  273. package/ios/utils/ENRMFeatureFlags.h +25 -0
  274. package/ios/utils/ENRMImageDownloader.h +30 -0
  275. package/ios/utils/ENRMImageDownloader.m +168 -0
  276. package/ios/utils/ENRMLatexErrorCoordinator.h +27 -0
  277. package/ios/utils/ENRMLatexErrorCoordinator.mm +75 -0
  278. package/ios/utils/ENRMLatexErrorReporting.h +13 -0
  279. package/ios/utils/ENRMLinkContextMenus.h +93 -0
  280. package/ios/utils/ENRMLinkContextMenus.m +178 -0
  281. package/ios/utils/ENRMLinkRegexConfig.h +30 -0
  282. package/ios/utils/ENRMLinkRegexConfig.mm +104 -0
  283. package/ios/utils/ENRMLinkRegexProps.h +23 -0
  284. package/ios/utils/ENRMLocalImageLoader.h +35 -0
  285. package/ios/utils/ENRMLocalImageLoader.m +111 -0
  286. package/ios/utils/ENRMMenuAction.h +27 -0
  287. package/ios/utils/ENRMMenuAction.m +33 -0
  288. package/ios/utils/ENRMSpoilerOverlayManager.h +15 -0
  289. package/ios/utils/ENRMSpoilerOverlayManager.m +19 -0
  290. package/ios/utils/ENRMSpoilerTapUtils.h +6 -0
  291. package/ios/utils/ENRMSpoilerTapUtils.m +11 -0
  292. package/ios/utils/ENRMTailFadeInAnimator.h +16 -0
  293. package/ios/utils/ENRMTailFadeInAnimator.m +161 -0
  294. package/ios/utils/ENRMTextHitTest.h +23 -0
  295. package/ios/utils/ENRMTextHitTest.m +20 -0
  296. package/ios/utils/ENRMTextInteractionUtils.h +20 -0
  297. package/ios/utils/ENRMTextInteractionUtils.m +15 -0
  298. package/ios/utils/ENRMTextRenderer.h +38 -0
  299. package/ios/utils/ENRMTextRenderer.m +54 -0
  300. package/ios/utils/ENRMTextViewSetup.h +132 -0
  301. package/ios/utils/ENRMUIKit.h +429 -0
  302. package/ios/utils/EditMenuUtils.h +105 -0
  303. package/ios/utils/EditMenuUtils.m +143 -0
  304. package/ios/utils/FactoidBackground.h +20 -0
  305. package/ios/utils/FactoidBackground.m +161 -0
  306. package/ios/utils/FontScaleObserver.h +10 -0
  307. package/ios/utils/FontScaleObserver.m +55 -0
  308. package/ios/utils/FontUtils.h +31 -0
  309. package/ios/utils/FontUtils.m +63 -0
  310. package/ios/utils/HTMLGenerator.h +25 -0
  311. package/ios/utils/HTMLGenerator.m +1041 -0
  312. package/ios/utils/HeightUpdateUtils.h +25 -0
  313. package/ios/utils/ImageRequestHeaderUtils.h +35 -0
  314. package/ios/utils/LastElementUtils.h +97 -0
  315. package/ios/utils/LinkContextMenuUtils.h +55 -0
  316. package/ios/utils/LinkPillContentUtils.h +46 -0
  317. package/ios/utils/LinkTapUtils.h +56 -0
  318. package/ios/utils/LinkTapUtils.m +139 -0
  319. package/ios/utils/ListMarkerDrawer.h +15 -0
  320. package/ios/utils/ListMarkerDrawer.m +239 -0
  321. package/ios/utils/MentionBackground.h +26 -0
  322. package/ios/utils/MentionBackground.m +86 -0
  323. package/ios/utils/ParagraphStyleUtils.h +87 -0
  324. package/ios/utils/ParagraphStyleUtils.m +484 -0
  325. package/ios/utils/PasteboardUtils.h +48 -0
  326. package/ios/utils/PasteboardUtils.m +166 -0
  327. package/ios/utils/RTFExportUtils.h +24 -0
  328. package/ios/utils/RTFExportUtils.m +299 -0
  329. package/ios/utils/RuntimeKeys.h +44 -0
  330. package/ios/utils/RuntimeKeys.m +13 -0
  331. package/ios/utils/SelectionColorUtils.h +14 -0
  332. package/ios/utils/StylePropsUtils.h +1340 -0
  333. package/ios/utils/TaskListTapUtils.h +6 -0
  334. package/ios/utils/TaskListTapUtils.m +14 -0
  335. package/ios/utils/TextViewLayoutManager.h +14 -0
  336. package/ios/utils/TextViewLayoutManager.mm +198 -0
  337. package/ios/utils/TiptapAccessibilityElementBuilder.h +43 -0
  338. package/ios/utils/TiptapAccessibilityElementBuilder.m +432 -0
  339. package/ios/utils/TiptapExtractor.h +17 -0
  340. package/ios/utils/TiptapExtractor.m +367 -0
  341. package/ios/views/ENRMTiptapTextView.h +25 -0
  342. package/ios/views/ENRMTiptapTextView.m +247 -0
  343. package/package.json +70 -6
  344. package/react-native.config.js +10 -0
  345. package/src/EnrichedTiptapTextNativeComponent.ts +739 -0
  346. package/src/RichText.tsx +164 -0
  347. package/src/admonitionDefaults.ts +58 -0
  348. package/src/darkModeTextStyle.ts +99 -0
  349. package/src/headingDefaults.ts +21 -0
  350. package/src/index.tsx +4 -0
  351. package/src/linkVariantUtils.ts +120 -0
  352. package/src/normalizeTiptapStyle.ts +397 -0
  353. package/src/rn-globals.d.ts +1 -0
  354. package/src/styleUtils.ts +107 -0
  355. package/src/types/TiptapStyle.ts +532 -0
  356. package/src/types/TiptapStyleInternal.ts +299 -0
  357. package/src/types/linkPill.ts +9 -0
  358. package/src/utils/isDev.ts +4 -0
@@ -0,0 +1,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
+ }
@@ -0,0 +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
+ }
@@ -0,0 +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
+ }
@@ -0,0 +1,101 @@
1
+ package com.renderrichtext.views
2
+
3
+ import android.graphics.Canvas
4
+ import android.graphics.Paint
5
+ import android.graphics.Path
6
+ import android.graphics.PorterDuff
7
+ import android.graphics.PorterDuffXfermode
8
+
9
+ /**
10
+ * Draws the copy glyph so Android matches the SF Symbol doc.on.doc rendered on
11
+ * iOS: two portrait document pages with a folded (dog-eared) top-right corner,
12
+ * a front page in the lower-left laid over a back page in the upper-right.
13
+ *
14
+ * The back page is punched out where the front page (plus a hairline of
15
+ * clearance) covers it, so the front reads as sitting on top exactly as the SF
16
+ * Symbol does, instead of both outlines crossing. The clear is done inside an
17
+ * offscreen layer so the punched region reveals whatever background the drawable
18
+ * sits on, without the glyph needing to know that color.
19
+ *
20
+ * One instance is held per drawable rather than shared: the paths and clear
21
+ * paint are reused across draws to keep draw() allocation-free, and two drawables
22
+ * of different sizes must not share those buffers. All coordinates use a 24-unit
23
+ * grid scaled to the drawable width, matching the grid the iOS symbol is authored
24
+ * on.
25
+ */
26
+ internal class CopyGlyph {
27
+ private val back = Path()
28
+ private val front = Path()
29
+ private val backFold = Path()
30
+ private val frontFold = Path()
31
+
32
+ // Color and colorFilter are irrelevant under PorterDuff.CLEAR; only the
33
+ // widened stroke (set per draw) matters, so this is configured once.
34
+ private val clearPaint =
35
+ Paint(Paint.ANTI_ALIAS_FLAG).apply {
36
+ style = Paint.Style.FILL_AND_STROKE
37
+ strokeJoin = Paint.Join.ROUND
38
+ strokeCap = Paint.Cap.ROUND
39
+ xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
40
+ }
41
+
42
+ fun draw(
43
+ canvas: Canvas,
44
+ width: Float,
45
+ stroke: Paint,
46
+ ) {
47
+ val u = width / 24f
48
+ val fold = 4f * u
49
+ val corner = 2f * u
50
+
51
+ buildPage(back, 9 * u, 1 * u, 20 * u, 17 * u, fold, corner)
52
+ buildPage(front, 3 * u, 7 * u, 14 * u, 23 * u, fold, corner)
53
+ buildFold(backFold, 20 * u, 1 * u, fold)
54
+ buildFold(frontFold, 14 * u, 7 * u, fold)
55
+ clearPaint.strokeWidth = stroke.strokeWidth * 3f
56
+
57
+ val saved = canvas.saveLayer(0f, 0f, width, width, null)
58
+ canvas.drawPath(back, stroke)
59
+ canvas.drawPath(backFold, stroke)
60
+ canvas.drawPath(front, clearPaint)
61
+ canvas.drawPath(front, stroke)
62
+ canvas.drawPath(frontFold, stroke)
63
+ canvas.restoreToCount(saved)
64
+ }
65
+
66
+ // A page outline whose top-right corner is cut back by fold, with the other
67
+ // three corners rounded by corner.
68
+ private fun buildPage(
69
+ path: Path,
70
+ l: Float,
71
+ t: Float,
72
+ r: Float,
73
+ b: Float,
74
+ fold: Float,
75
+ corner: Float,
76
+ ) {
77
+ path.rewind()
78
+ path.moveTo(l, t + corner)
79
+ path.quadTo(l, t, l + corner, t)
80
+ path.lineTo(r - fold, t)
81
+ path.lineTo(r, t + fold)
82
+ path.lineTo(r, b - corner)
83
+ path.quadTo(r, b, r - corner, b)
84
+ path.lineTo(l + corner, b)
85
+ path.quadTo(l, b, l, b - corner)
86
+ path.close()
87
+ }
88
+
89
+ // The two inner edges of the folded-over corner, at the page's top-right.
90
+ private fun buildFold(
91
+ path: Path,
92
+ r: Float,
93
+ t: Float,
94
+ fold: Float,
95
+ ) {
96
+ path.rewind()
97
+ path.moveTo(r - fold, t)
98
+ path.lineTo(r - fold, t + fold)
99
+ path.lineTo(r, t + fold)
100
+ }
101
+ }
@@ -0,0 +1,40 @@
1
+ package com.renderrichtext.views
2
+
3
+ import android.graphics.Canvas
4
+ import android.graphics.Paint
5
+ import android.graphics.Path
6
+ import android.graphics.RectF
7
+
8
+ /**
9
+ * Material "wrap_text" glyph as strokes on a 24-unit grid, drawn with the same
10
+ * paint as [CopyGlyph] so the two header buttons match in weight.
11
+ */
12
+ internal class WrapGlyph {
13
+ private val lines = Path()
14
+ private val arrow = Path()
15
+ private val loop = RectF()
16
+
17
+ fun draw(
18
+ canvas: Canvas,
19
+ width: Float,
20
+ stroke: Paint,
21
+ ) {
22
+ val u = width / 24f
23
+ lines.rewind()
24
+ lines.moveTo(4 * u, 6 * u)
25
+ lines.lineTo(20 * u, 6 * u)
26
+ lines.moveTo(4 * u, 18 * u)
27
+ lines.lineTo(10 * u, 18 * u)
28
+ lines.moveTo(4 * u, 12 * u)
29
+ lines.lineTo(17 * u, 12 * u)
30
+ loop.set(15 * u, 12 * u, 19 * u, 16 * u)
31
+ lines.arcTo(loop, -90f, 180f)
32
+ lines.lineTo(13 * u, 16 * u)
33
+ arrow.rewind()
34
+ arrow.moveTo(15 * u, 14 * u)
35
+ arrow.lineTo(13 * u, 16 * u)
36
+ arrow.lineTo(15 * u, 18 * u)
37
+ canvas.drawPath(lines, stroke)
38
+ canvas.drawPath(arrow, stroke)
39
+ }
40
+ }
@@ -0,0 +1,52 @@
1
+ cmake_minimum_required(VERSION 3.13)
2
+ set(CMAKE_VERBOSE_MAKEFILE ON)
3
+
4
+ set(LIB_LITERAL RichTextSpec)
5
+ set(LIB_TARGET_NAME react_codegen_${LIB_LITERAL})
6
+
7
+ set(LIB_ANDROID_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
8
+ set(LIB_ANDROID_GENERATED_JNI_DIR ${LIB_ANDROID_DIR}/build/generated/source/codegen/jni)
9
+ set(LIB_ANDROID_GENERATED_COMPONENTS_DIR ${LIB_ANDROID_GENERATED_JNI_DIR}/react/renderer/components/${LIB_LITERAL})
10
+ set(CPP_ROOT ${LIB_ANDROID_DIR}/../cpp)
11
+
12
+ file(GLOB PARSER_SOURCES "${CPP_ROOT}/parser/*.cpp")
13
+ file(GLOB LIB_CODEGEN_SRCS CONFIGURE_DEPENDS
14
+ ${LIB_ANDROID_GENERATED_JNI_DIR}/*.cpp
15
+ ${LIB_ANDROID_GENERATED_COMPONENTS_DIR}/*.cpp)
16
+ file(GLOB LIB_CUSTOM_JNI_SRCS CONFIGURE_DEPENDS
17
+ ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
18
+ ${CMAKE_CURRENT_SOURCE_DIR}/react/renderer/components/${LIB_LITERAL}/*.cpp)
19
+
20
+ add_library(
21
+ ${LIB_TARGET_NAME}
22
+ SHARED
23
+ ${LIB_CODEGEN_SRCS}
24
+ ${LIB_CUSTOM_JNI_SRCS}
25
+ ${PARSER_SOURCES}
26
+ ${LIB_ANDROID_DIR}/src/main/cpp/jni-adapter.cpp
27
+ )
28
+
29
+ target_include_directories(
30
+ ${LIB_TARGET_NAME}
31
+ PUBLIC
32
+ ${CMAKE_CURRENT_SOURCE_DIR}
33
+ ${CMAKE_CURRENT_SOURCE_DIR}/react/renderer/components/${LIB_LITERAL}
34
+ ${LIB_ANDROID_GENERATED_JNI_DIR}
35
+ ${LIB_ANDROID_GENERATED_COMPONENTS_DIR}
36
+ ${CPP_ROOT}/parser
37
+ ${CPP_ROOT}/vendor
38
+ )
39
+
40
+ find_package(fbjni REQUIRED CONFIG)
41
+ find_package(ReactAndroid REQUIRED CONFIG)
42
+ find_library(LOG_LIB log)
43
+
44
+ target_link_libraries(
45
+ ${LIB_TARGET_NAME}
46
+ ${LOG_LIB}
47
+ fbjni::fbjni
48
+ ReactAndroid::jsi
49
+ ReactAndroid::reactnative
50
+ )
51
+
52
+ target_compile_reactnative_options(${LIB_TARGET_NAME} PRIVATE)
@@ -0,0 +1,30 @@
1
+ #pragma once
2
+
3
+ #include "TiptapTextMeasurementManager.h"
4
+ #include "TiptapTextShadowNode.h"
5
+
6
+ #include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
7
+ #include <react/renderer/core/ConcreteComponentDescriptor.h>
8
+
9
+ namespace facebook::react {
10
+
11
+ class EnrichedTiptapTextComponentDescriptor final : public ConcreteComponentDescriptor<TiptapTextShadowNode> {
12
+ public:
13
+ EnrichedTiptapTextComponentDescriptor(const ComponentDescriptorParameters &parameters)
14
+ : ConcreteComponentDescriptor(parameters),
15
+ measurementsManager_(std::make_shared<TiptapTextMeasurementManager>(contextContainer_)) {}
16
+
17
+ void adopt(ShadowNode &shadowNode) const override {
18
+ ConcreteComponentDescriptor::adopt(shadowNode);
19
+ auto &tiptapTextShadowNode = static_cast<TiptapTextShadowNode &>(shadowNode);
20
+ tiptapTextShadowNode.setMeasurementsManager(measurementsManager_);
21
+ }
22
+
23
+ private:
24
+ const std::shared_ptr<TiptapTextMeasurementManager> measurementsManager_;
25
+ };
26
+
27
+ void RichTextSpec_registerComponentDescriptorsFromCodegen(
28
+ std::shared_ptr<const ComponentDescriptorProviderRegistry> registry);
29
+
30
+ } // namespace facebook::react
@@ -0,0 +1,29 @@
1
+ #pragma once
2
+
3
+ #include "TiptapTextMeasurementManager.h"
4
+ #include "TiptapTextShadowNode.h"
5
+
6
+ #include <react/renderer/core/ConcreteComponentDescriptor.h>
7
+
8
+ namespace facebook::react {
9
+
10
+ class TiptapTextComponentDescriptor final : public ConcreteComponentDescriptor<TiptapTextShadowNode> {
11
+ public:
12
+ TiptapTextComponentDescriptor(const ComponentDescriptorParameters &parameters)
13
+ : ConcreteComponentDescriptor(parameters),
14
+ measurementsManager_(std::make_shared<TiptapTextMeasurementManager>(contextContainer_)) {}
15
+
16
+ void adopt(ShadowNode &shadowNode) const override {
17
+ ConcreteComponentDescriptor::adopt(shadowNode);
18
+ auto &tiptapTextShadowNode = static_cast<TiptapTextShadowNode &>(shadowNode);
19
+
20
+ // TiptapTextShadowNode uses TiptapTextMeasurementManager
21
+ // to provide measurements to Yoga.
22
+ tiptapTextShadowNode.setMeasurementsManager(measurementsManager_);
23
+ }
24
+
25
+ private:
26
+ const std::shared_ptr<TiptapTextMeasurementManager> measurementsManager_;
27
+ };
28
+
29
+ } // namespace facebook::react
@@ -0,0 +1,45 @@
1
+ #include "TiptapTextMeasurementManager.h"
2
+ #include "conversions.h"
3
+
4
+ #include <fbjni/fbjni.h>
5
+ #include <react/jni/ReadableNativeMap.h>
6
+ #include <react/renderer/core/conversions.h>
7
+
8
+ using namespace facebook::jni;
9
+
10
+ namespace facebook::react {
11
+
12
+ Size TiptapTextMeasurementManager::measure(SurfaceId surfaceId, int viewTag, const EnrichedTiptapTextProps &props,
13
+ LayoutConstraints layoutConstraints) const {
14
+ const jni::global_ref<jobject> &fabricUIManager = contextContainer_->at<jni::global_ref<jobject>>("FabricUIManager");
15
+
16
+ static const auto measure =
17
+ facebook::jni::findClassStatic("com/facebook/react/fabric/FabricUIManager")
18
+ ->getMethod<jlong(jint, jstring, ReadableMap::javaobject, ReadableMap::javaobject, ReadableMap::javaobject,
19
+ jfloat, jfloat, jfloat, jfloat)>("measure");
20
+
21
+ auto minimumSize = layoutConstraints.minimumSize;
22
+ auto maximumSize = layoutConstraints.maximumSize;
23
+
24
+ local_ref<JString> componentName = make_jstring("EnrichedTiptapText");
25
+
26
+ // Prepare extraData map with viewTag
27
+ folly::dynamic extraData = folly::dynamic::object();
28
+ extraData["viewTag"] = viewTag;
29
+ local_ref<ReadableNativeMap::javaobject> extraDataRNM = ReadableNativeMap::newObjectCxxArgs(extraData);
30
+ local_ref<ReadableMap::javaobject> extraDataRM =
31
+ make_local(reinterpret_cast<ReadableMap::javaobject>(extraDataRNM.get()));
32
+
33
+ // Prepare layout metrics affecting props
34
+ auto serializedProps = toDynamic(props);
35
+ local_ref<ReadableNativeMap::javaobject> propsRNM = ReadableNativeMap::newObjectCxxArgs(serializedProps);
36
+ local_ref<ReadableMap::javaobject> propsRM = make_local(reinterpret_cast<ReadableMap::javaobject>(propsRNM.get()));
37
+
38
+ auto measurement = yogaMeassureToSize(measure(fabricUIManager, surfaceId, componentName.get(), extraDataRM.get(),
39
+ propsRM.get(), nullptr, minimumSize.width, maximumSize.width,
40
+ minimumSize.height, maximumSize.height));
41
+
42
+ return measurement;
43
+ }
44
+
45
+ } // namespace facebook::react