react-native-enriched-markdown-scaffold 0.7.4-scaffold.9 → 1.0.2-scaffold.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (505) hide show
  1. package/README.md +54 -8
  2. package/ReactNativeEnrichedMarkdown.podspec +82 -73
  3. package/android/build.gradle +188 -1
  4. package/android/consumer-rules.pro +1 -1
  5. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +27 -0
  6. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +7 -0
  7. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerDelegate.java +24 -0
  8. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerInterface.java +8 -0
  9. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +27 -0
  10. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +7 -0
  11. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +223 -0
  12. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +183 -0
  13. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +65 -0
  14. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +1086 -61
  15. package/android/src/main/baseline-prof.txt +1 -1
  16. package/android/src/main/cpp/jni-adapter.cpp +74 -0
  17. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +351 -13
  18. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +62 -0
  19. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +85 -0
  20. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +160 -1
  21. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextLayoutManager.kt +10 -1
  22. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +76 -0
  23. package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +126 -10
  24. package/android/src/main/java/com/swmansion/enriched/markdown/events/CopyPressEvent.kt +24 -0
  25. package/android/src/main/java/com/swmansion/enriched/markdown/events/CopyRequestEvent.kt +28 -0
  26. package/android/src/main/java/com/swmansion/enriched/markdown/events/LinkLayoutEvent.kt +36 -0
  27. package/android/src/main/java/com/swmansion/enriched/markdown/events/SelectionChangeEvent.kt +43 -0
  28. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputManager.kt +54 -4
  29. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +923 -462
  30. package/android/src/main/java/com/swmansion/enriched/markdown/input/MarkdownClipboard.kt +42 -0
  31. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/BlockEditCoordinator.kt +196 -0
  32. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/ClipboardCoordinator.kt +73 -0
  33. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditContext.kt +19 -0
  34. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditPipeline.kt +248 -0
  35. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditSession.kt +52 -0
  36. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/InputConnectionWrapper.kt +108 -7
  37. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/LinkCoordinator.kt +69 -0
  38. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MarkdownTextWatcher.kt +3 -3
  39. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MentionCoordinator.kt +118 -0
  40. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeStateEvent.kt +26 -0
  41. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnContextMenuItemPressEvent.kt +26 -0
  42. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnInputKeyPressEvent.kt +24 -0
  43. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnPasteEvent.kt +24 -0
  44. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockStore.kt +254 -0
  45. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/FormattingStore.kt +80 -87
  46. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputFormatter.kt +109 -1
  47. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +116 -22
  48. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/MarkdownSerializer.kt +167 -38
  49. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/RangeEditAdjustment.kt +149 -0
  50. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputEventEmitter.kt +66 -5
  51. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +4 -2
  52. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockRange.kt +27 -0
  53. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockType.kt +48 -0
  54. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/FormattingRange.kt +9 -4
  55. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/InputFormatterStyle.kt +39 -2
  56. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathAtom.kt +20 -0
  57. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +1 -1
  58. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MutableRangeBounds.kt +11 -0
  59. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputBulletSpan.kt +82 -0
  60. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputHeadingSpan.kt +58 -0
  61. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputListItemSpacingSpan.kt +37 -0
  62. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputOrderedListMarkerSpan.kt +63 -0
  63. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/BlockHandler.kt +54 -0
  64. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/HeadingBlockHandler.kt +27 -0
  65. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/OrderedListBlockHandler.kt +38 -0
  66. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/UnorderedListBlockHandler.kt +37 -0
  67. package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +8 -26
  68. package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +1 -0
  69. package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +1 -0
  70. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +9 -2
  71. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +100 -12
  72. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +16 -1
  73. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +4 -0
  74. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt +37 -7
  75. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +2 -1
  76. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +74 -18
  77. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +43 -4
  78. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +9 -1
  79. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SoftBreakRenderer.kt +16 -0
  80. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +35 -28
  81. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +24 -0
  82. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +174 -24
  83. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +20 -82
  84. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +13 -16
  85. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
  86. package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +1 -1
  87. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +182 -46
  88. package/android/src/main/java/com/swmansion/enriched/markdown/spans/InlineChipPainter.kt +140 -0
  89. package/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkChipSpans.kt +177 -0
  90. package/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt +1 -6
  91. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListItemSpacingSpan.kt +33 -0
  92. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListMarkerAnchorSpan.kt +38 -0
  93. package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +2 -0
  94. package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -1
  95. package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +3 -2
  96. package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +3 -2
  97. package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +6 -0
  98. package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +26 -0
  99. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +7 -1
  100. package/android/src/main/java/com/swmansion/enriched/markdown/styles/InlineMathStyle.kt +16 -1
  101. package/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkStyle.kt +36 -1
  102. package/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkVariantEntry.kt +7 -3
  103. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +4 -1
  104. package/android/src/main/java/com/swmansion/enriched/markdown/styles/MathStyle.kt +3 -0
  105. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +13 -4
  106. package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +6 -0
  107. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockHighlighter.kt +90 -0
  108. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockNode.kt +57 -0
  109. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/FeatureFlags.kt +1 -0
  110. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownSegment.kt +9 -0
  111. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +84 -7
  112. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/ReadableMapExtensions.kt +3 -0
  113. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/RenderedSegment.kt +10 -0
  114. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentSignature.kt +1 -0
  115. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/StreamingMarkdownFilter.kt +83 -5
  116. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +4 -0
  117. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +74 -44
  118. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/PasteTextUtils.kt +52 -0
  119. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +26 -3
  120. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +22 -9
  121. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/LocalImageLoader.kt +161 -0
  122. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/HTMLGenerator.kt +2 -1
  123. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/MarkdownExtractor.kt +6 -0
  124. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/TextPaintExtensions.kt +23 -0
  125. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/CheckboxTouchHelper.kt +7 -0
  126. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +41 -21
  127. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt +15 -8
  128. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/HeadlessActionMode.kt +88 -0
  129. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLayoutCollector.kt +100 -0
  130. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLongPressMovementMethod.kt +58 -27
  131. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +72 -16
  132. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionChangeReporter.kt +232 -0
  133. package/android/src/main/java/com/swmansion/enriched/markdown/views/BlockMenuOptions.kt +64 -0
  134. package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +414 -0
  135. package/android/src/main/java/com/swmansion/enriched/markdown/views/ContextMenuPopup.kt +9 -6
  136. package/android/src/main/java/com/swmansion/enriched/markdown/views/CopyGlyph.kt +101 -0
  137. package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +61 -11
  138. package/android/src/main/jni/CMakeLists.txt +53 -0
  139. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.cpp +10 -0
  140. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +11 -2
  141. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +10 -0
  142. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +12 -2
  143. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.cpp +9 -0
  144. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.h +24 -0
  145. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +16 -0
  146. package/android/src/math/java/com/swmansion/enriched/markdown/input/math/MathChipControllerImpl.kt +21 -4
  147. package/android/src/math/java/com/swmansion/enriched/markdown/renderer/MathInlineRenderer.kt +8 -2
  148. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +1 -1
  149. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathInlineSpan.kt +13 -6
  150. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathMeasureHelper.kt +2 -1
  151. package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +26 -8
  152. package/cpp/highlight/CodeBlockHighlighter.cpp +284 -0
  153. package/cpp/highlight/CodeBlockHighlighter.hpp +66 -0
  154. package/cpp/highlight/CodeBlockLanguages.cpp +138 -0
  155. package/cpp/highlight/CodeBlockLanguages.hpp +25 -0
  156. package/cpp/highlight/HighlightGrammars.hpp +28 -0
  157. package/cpp/highlight/code_highlight_podspec.rb +211 -0
  158. package/cpp/highlight/gen-registry.mjs +155 -0
  159. package/cpp/highlight/grammar-versions.json +159 -0
  160. package/cpp/highlight/vendor/generated/generated_queries.h +1665 -0
  161. package/cpp/highlight/vendor/generated/generated_registry.cpp +59 -0
  162. package/cpp/parser/MD4CParser.cpp +173 -61
  163. package/cpp/parser/MD4CParser.hpp +1 -0
  164. package/cpp/parser/MarkdownASTNode.hpp +2 -1
  165. package/cpp/wasm/ASTSerializer.cpp +2 -0
  166. package/cpp/wasm/build.sh +1 -0
  167. package/cpp/wasm/md4c_wasm.cpp +3 -1
  168. package/docs/ACCESSIBILITY.md +14 -2
  169. package/docs/API_REFERENCE.md +405 -12
  170. package/docs/BREAKING_CHANGES.md +129 -0
  171. package/docs/CODE_HIGHLIGHT.md +133 -0
  172. package/docs/COPY_OPTIONS.md +61 -3
  173. package/docs/ELEMENTS_STRUCTURE.md +52 -4
  174. package/docs/IMAGE_CACHING.md +30 -0
  175. package/docs/INPUT.md +110 -11
  176. package/docs/LATEX_MATH.md +87 -45
  177. package/docs/MACOS.md +1 -1
  178. package/docs/MARKDOWN_STREAMING.md +27 -1
  179. package/docs/MENTIONS.md +8 -1
  180. package/docs/NATIVE_ASSETS.md +127 -0
  181. package/docs/RTL.md +1 -1
  182. package/docs/STYLES.md +73 -6
  183. package/docs/TESTING.md +112 -0
  184. package/docs/TEXT.md +18 -6
  185. package/docs/WEB.md +4 -1
  186. package/ios/EnrichedMarkdown.h +7 -0
  187. package/ios/EnrichedMarkdown.mm +583 -76
  188. package/ios/EnrichedMarkdownText.h +7 -0
  189. package/ios/EnrichedMarkdownText.mm +299 -73
  190. package/ios/attachments/ENRMImageAttachment.h +9 -0
  191. package/ios/attachments/ENRMImageAttachment.m +143 -40
  192. package/ios/attachments/ENRMMathInlineAttachment+macOS.m +2 -1
  193. package/ios/attachments/ENRMMathInlineAttachment.h +5 -0
  194. package/ios/attachments/ENRMMathInlineAttachment.m +50 -82
  195. package/ios/attachments/ENRMMathInlineAttachmentShared.h +2 -0
  196. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +223 -0
  197. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +183 -0
  198. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +65 -0
  199. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +1086 -61
  200. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +181 -2
  201. package/ios/input/ENRMAutoLinkDetector.h +2 -1
  202. package/ios/input/ENRMAutoLinkDetector.mm +79 -41
  203. package/ios/input/ENRMBlockEditCoordinator.h +71 -0
  204. package/ios/input/ENRMBlockEditCoordinator.mm +195 -0
  205. package/ios/input/ENRMBlockRange.h +28 -0
  206. package/ios/input/ENRMBlockRange.mm +30 -0
  207. package/ios/input/ENRMBlockStore.h +56 -0
  208. package/ios/input/ENRMBlockStore.mm +275 -0
  209. package/ios/input/ENRMClipboardCoordinator.h +45 -0
  210. package/ios/input/ENRMClipboardCoordinator.mm +120 -0
  211. package/ios/input/ENRMDetectorPipeline.h +2 -1
  212. package/ios/input/ENRMEditPipeline.h +76 -0
  213. package/ios/input/ENRMEditPipeline.mm +228 -0
  214. package/ios/input/ENRMEditSession.h +36 -0
  215. package/ios/input/ENRMEditSession.mm +63 -0
  216. package/ios/input/ENRMFormattingStore.h +17 -0
  217. package/ios/input/ENRMFormattingStore.mm +95 -105
  218. package/ios/input/ENRMInputBlockType.h +91 -0
  219. package/ios/input/ENRMInputBlockType.mm +5 -0
  220. package/ios/input/ENRMInputDecorationDrawer.h +18 -0
  221. package/ios/input/ENRMInputEventEmitter.h +56 -0
  222. package/ios/input/ENRMInputEventEmitter.mm +308 -0
  223. package/ios/input/ENRMInputFormatter.h +29 -69
  224. package/ios/input/ENRMInputFormatter.mm +216 -124
  225. package/ios/input/ENRMInputFormatterStyle.h +99 -0
  226. package/ios/input/ENRMInputFormatterStyle.mm +188 -0
  227. package/ios/input/ENRMInputLayoutManager.h +9 -0
  228. package/ios/input/ENRMInputLayoutManager.mm +30 -0
  229. package/ios/input/ENRMInputListMarkerDrawer.h +32 -0
  230. package/ios/input/ENRMInputListMarkerDrawer.mm +426 -0
  231. package/ios/input/ENRMInputParser.h +5 -6
  232. package/ios/input/ENRMInputParser.mm +461 -178
  233. package/ios/input/ENRMInputRemend.mm +2 -2
  234. package/ios/input/ENRMInputStyleStateBuilder.h +40 -0
  235. package/ios/input/ENRMInputStyleStateBuilder.mm +60 -0
  236. package/ios/input/ENRMInputTextView.mm +103 -8
  237. package/ios/input/ENRMInputTypingAttributesController.h +42 -0
  238. package/ios/input/ENRMInputTypingAttributesController.mm +203 -0
  239. package/ios/input/ENRMLinkCoordinator.h +41 -0
  240. package/ios/input/ENRMLinkCoordinator.mm +89 -0
  241. package/ios/input/ENRMMarkdownSerializer.h +29 -5
  242. package/ios/input/ENRMMarkdownSerializer.mm +170 -48
  243. package/ios/input/ENRMMathAtom.h +26 -0
  244. package/ios/input/ENRMMathAtom.mm +12 -0
  245. package/ios/input/ENRMMentionCoordinator.h +45 -0
  246. package/ios/input/ENRMMentionCoordinator.mm +167 -0
  247. package/ios/input/ENRMRangeEditAdjustment.h +38 -0
  248. package/ios/input/ENRMRangeEditAdjustment.mm +91 -0
  249. package/ios/input/ENRMRangeStoreUtils.h +39 -0
  250. package/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm +6 -6
  251. package/ios/input/EnrichedMarkdownTextInput+Internal.h +11 -3
  252. package/ios/input/EnrichedMarkdownTextInput.h +7 -1
  253. package/ios/input/EnrichedMarkdownTextInput.mm +1089 -1023
  254. package/ios/input/InputStylePropsUtils.h +109 -68
  255. package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.mm +2 -1
  256. package/ios/input/styles/ENRMBlockHandler.h +46 -0
  257. package/ios/input/styles/ENRMHeadingBlockHandler.h +15 -0
  258. package/ios/input/styles/ENRMHeadingBlockHandler.mm +38 -0
  259. package/ios/input/styles/ENRMOrderedListBlockHandler.h +14 -0
  260. package/ios/input/styles/ENRMOrderedListBlockHandler.mm +48 -0
  261. package/ios/input/styles/ENRMUnorderedListBlockHandler.h +15 -0
  262. package/ios/input/styles/ENRMUnorderedListBlockHandler.mm +51 -0
  263. package/ios/internals/ENRMViewFreeMeasurement.h +331 -0
  264. package/ios/internals/EnrichedMarkdownShadowNode.h +1 -3
  265. package/ios/internals/EnrichedMarkdownShadowNode.mm +16 -20
  266. package/ios/internals/EnrichedMarkdownTextShadowNode.h +1 -3
  267. package/ios/internals/EnrichedMarkdownTextShadowNode.mm +15 -20
  268. package/ios/internals/MeasurementCache.h +41 -9
  269. package/ios/internals/ShadowMeasurementUtils.h +63 -58
  270. package/ios/math/ENRMMathChipController.h +74 -0
  271. package/ios/math/ENRMMathChipController.mm +476 -0
  272. package/ios/math/ENRMRaTeXBridge.swift +27 -6
  273. package/ios/parser/ENRMMarkdownParser.h +1 -8
  274. package/ios/parser/ENRMMarkdownParser.mm +2 -11
  275. package/ios/parser/MarkdownASTNode.h +2 -1
  276. package/ios/parser/MarkdownParserBridge.mm +4 -0
  277. package/ios/renderer/AttributedRenderer.m +20 -2
  278. package/ios/renderer/BaseRenderer.h +17 -2
  279. package/ios/renderer/BaseRenderer.m +30 -0
  280. package/ios/renderer/BlockquoteRenderer.h +1 -1
  281. package/ios/renderer/BlockquoteRenderer.m +144 -35
  282. package/ios/renderer/CodeBlockRenderer.h +1 -1
  283. package/ios/renderer/CodeBlockRenderer.m +27 -23
  284. package/ios/renderer/CodeRenderer.h +1 -1
  285. package/ios/renderer/CodeRenderer.m +3 -1
  286. package/ios/renderer/ENRMImageRenderer.h +1 -1
  287. package/ios/renderer/ENRMImageRenderer.m +5 -1
  288. package/ios/renderer/ENRMMathInlineRenderer.h +1 -1
  289. package/ios/renderer/ENRMMathInlineRenderer.m +6 -1
  290. package/ios/renderer/ENRMSpoilerRenderer.h +1 -1
  291. package/ios/renderer/ENRMSpoilerRenderer.m +3 -1
  292. package/ios/renderer/EmphasisRenderer.h +1 -1
  293. package/ios/renderer/EmphasisRenderer.m +3 -1
  294. package/ios/renderer/HeadingRenderer.h +1 -1
  295. package/ios/renderer/HeadingRenderer.m +13 -6
  296. package/ios/renderer/HighlightRenderer.h +1 -1
  297. package/ios/renderer/HighlightRenderer.m +3 -1
  298. package/ios/renderer/LinkRenderer.h +1 -1
  299. package/ios/renderer/LinkRenderer.m +50 -16
  300. package/ios/renderer/ListItemRenderer.h +13 -1
  301. package/ios/renderer/ListItemRenderer.m +102 -44
  302. package/ios/renderer/ListRenderer.h +2 -2
  303. package/ios/renderer/ListRenderer.m +63 -25
  304. package/ios/renderer/ParagraphRenderer.h +1 -1
  305. package/ios/renderer/ParagraphRenderer.m +16 -8
  306. package/ios/renderer/RenderContext.h +10 -0
  307. package/ios/renderer/RenderContext.m +44 -0
  308. package/ios/renderer/RendererFactory.m +14 -0
  309. package/ios/renderer/StrikethroughRenderer.h +1 -1
  310. package/ios/renderer/StrikethroughRenderer.m +3 -1
  311. package/ios/renderer/StrongRenderer.h +1 -1
  312. package/ios/renderer/StrongRenderer.m +3 -1
  313. package/ios/renderer/SubscriptRenderer.h +1 -1
  314. package/ios/renderer/SubscriptRenderer.m +3 -1
  315. package/ios/renderer/SuperscriptRenderer.h +1 -1
  316. package/ios/renderer/SuperscriptRenderer.m +3 -1
  317. package/ios/renderer/TextRenderer.h +2 -2
  318. package/ios/renderer/TextRenderer.m +3 -1
  319. package/ios/renderer/ThematicBreakRenderer.h +1 -1
  320. package/ios/renderer/ThematicBreakRenderer.m +3 -1
  321. package/ios/renderer/UnderlineRenderer.h +1 -1
  322. package/ios/renderer/UnderlineRenderer.m +3 -1
  323. package/ios/styles/StyleConfig.h +42 -0
  324. package/ios/styles/StyleConfig.mm +216 -0
  325. package/ios/utils/BlockquoteBorder.h +6 -0
  326. package/ios/utils/BlockquoteBorder.m +249 -52
  327. package/ios/utils/CodeBackground.m +3 -65
  328. package/ios/utils/CodeBlockBackground.m +16 -2
  329. package/ios/utils/ENRMAtomicSize.h +65 -0
  330. package/ios/utils/ENRMBlockMenu.h +66 -0
  331. package/ios/utils/ENRMChipDrawing.h +24 -0
  332. package/ios/utils/ENRMChipDrawing.m +83 -0
  333. package/ios/utils/ENRMCodeBlockContent.h +37 -0
  334. package/ios/utils/ENRMCodeBlockContent.mm +79 -0
  335. package/ios/utils/ENRMCodeBlockHighlighter.h +37 -0
  336. package/ios/utils/ENRMCodeBlockHighlighter.mm +51 -0
  337. package/ios/utils/ENRMFeatureFlags.h +7 -0
  338. package/ios/utils/ENRMImageDownloader.h +11 -1
  339. package/ios/utils/ENRMImageDownloader.m +60 -16
  340. package/ios/utils/ENRMLinkChip.h +70 -0
  341. package/ios/utils/ENRMLinkChip.m +213 -0
  342. package/ios/utils/ENRMLinkLayout.h +50 -0
  343. package/ios/utils/ENRMLinkLayout.m +45 -0
  344. package/ios/utils/ENRMLocalImageLoader.h +31 -0
  345. package/ios/utils/ENRMLocalImageLoader.m +68 -0
  346. package/ios/utils/ENRMMathFallback.h +26 -0
  347. package/ios/utils/ENRMMathFallback.m +18 -0
  348. package/ios/utils/ENRMSelectionChange.h +120 -0
  349. package/ios/utils/ENRMSelectionChange.m +282 -0
  350. package/ios/utils/ENRMTextViewSetup.h +35 -17
  351. package/ios/utils/EditMenuUtils+macOS.m +4 -1
  352. package/ios/utils/EditMenuUtils.h +35 -6
  353. package/ios/utils/EditMenuUtils.m +188 -11
  354. package/ios/utils/HTMLGenerator.m +2 -1
  355. package/ios/utils/ImageRequestHeaderUtils.h +35 -0
  356. package/ios/utils/LastElementUtils.h +1 -0
  357. package/ios/utils/ListMarkerDrawer.m +29 -42
  358. package/ios/utils/MarkdownASTSerializer.m +4 -0
  359. package/ios/utils/MarkdownAccessibilityElementBuilder.m +3 -1
  360. package/ios/utils/MarkdownExtractor.m +2 -1
  361. package/ios/utils/ParagraphStyleUtils.h +5 -0
  362. package/ios/utils/ParagraphStyleUtils.m +77 -17
  363. package/ios/utils/RTFExportUtils.m +2 -0
  364. package/ios/utils/RenderedMarkdownSegment.h +13 -1
  365. package/ios/utils/RenderedMarkdownSegment.m +20 -0
  366. package/ios/utils/SegmentRenderer.m +17 -4
  367. package/ios/utils/StreamingMarkdownFilter.h +11 -1
  368. package/ios/utils/StreamingMarkdownFilter.m +98 -2
  369. package/ios/utils/StylePropsUtils.h +110 -1
  370. package/ios/utils/TaskListTapUtils.m +24 -0
  371. package/ios/utils/TextViewLayoutManager.mm +3 -0
  372. package/ios/views/ENRMCodeBlockContainerView.h +60 -0
  373. package/ios/views/ENRMCodeBlockContainerView.m +569 -0
  374. package/ios/views/ENRMMathContainerView.h +23 -0
  375. package/ios/views/ENRMMathContainerView.m +87 -20
  376. package/ios/views/TableContainerView.h +32 -0
  377. package/ios/views/TableContainerView.m +291 -175
  378. package/jest.d.ts +1 -0
  379. package/jest.js +5 -0
  380. package/lib/module/EnrichedMarkdownNativeComponent.ts +203 -1
  381. package/lib/module/EnrichedMarkdownTextInput.js +84 -5
  382. package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
  383. package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
  384. package/lib/module/EnrichedMarkdownTextNativeComponent.ts +204 -1
  385. package/lib/module/headingDefaults.js +34 -0
  386. package/lib/module/headingDefaults.js.map +1 -0
  387. package/lib/module/index.js.map +1 -1
  388. package/lib/module/jest/index.js +205 -0
  389. package/lib/module/jest/index.js.map +1 -0
  390. package/lib/module/native/EnrichedMarkdownText.js +199 -15
  391. package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
  392. package/lib/module/normalizeMarkdownStyle.js +98 -23
  393. package/lib/module/normalizeMarkdownStyle.js.map +1 -1
  394. package/lib/module/normalizeMarkdownStyle.web.js +73 -22
  395. package/lib/module/normalizeMarkdownStyle.web.js.map +1 -1
  396. package/lib/module/normalizeMarkdownTextInputStyle.js +62 -15
  397. package/lib/module/normalizeMarkdownTextInputStyle.js.map +1 -1
  398. package/lib/module/normalizeMenuItem.js +1 -1
  399. package/lib/module/utils/textInputState.js +26 -0
  400. package/lib/module/utils/textInputState.js.map +1 -0
  401. package/lib/module/web/EnrichedMarkdownText.js +15 -8
  402. package/lib/module/web/EnrichedMarkdownText.js.map +1 -1
  403. package/lib/module/web/parseMarkdown.js +4 -3
  404. package/lib/module/web/parseMarkdown.js.map +1 -1
  405. package/lib/module/web/renderers/InlineRenderers.js +102 -3
  406. package/lib/module/web/renderers/InlineRenderers.js.map +1 -1
  407. package/lib/module/web/renderers/ListRenderers.js +7 -2
  408. package/lib/module/web/renderers/ListRenderers.js.map +1 -1
  409. package/lib/module/web/renderers/index.js +7 -4
  410. package/lib/module/web/renderers/index.js.map +1 -1
  411. package/lib/module/web/styles.js +101 -6
  412. package/lib/module/web/styles.js.map +1 -1
  413. package/lib/module/web/utils.js +14 -0
  414. package/lib/module/web/utils.js.map +1 -1
  415. package/lib/module/web/wasm/md4c.js +0 -0
  416. package/lib/module/web/wasm/md4c.js.map +1 -1
  417. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +185 -2
  418. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
  419. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +94 -9
  420. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
  421. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +69 -5
  422. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
  423. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +185 -2
  424. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
  425. package/lib/typescript/src/headingDefaults.d.ts +9 -0
  426. package/lib/typescript/src/headingDefaults.d.ts.map +1 -0
  427. package/lib/typescript/src/index.d.ts +3 -3
  428. package/lib/typescript/src/index.d.ts.map +1 -1
  429. package/lib/typescript/src/index.web.d.ts +2 -2
  430. package/lib/typescript/src/index.web.d.ts.map +1 -1
  431. package/lib/typescript/src/jest/index.d.ts +6 -0
  432. package/lib/typescript/src/jest/index.d.ts.map +1 -0
  433. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +5 -5
  434. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +1 -1
  435. package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
  436. package/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +1 -1
  437. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts +19 -5
  438. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts.map +1 -1
  439. package/lib/typescript/src/types/MarkdownStyle.d.ts +122 -5
  440. package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -1
  441. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +39 -0
  442. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -1
  443. package/lib/typescript/src/types/MarkdownTextProps.d.ts +207 -10
  444. package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
  445. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts +60 -1
  446. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts.map +1 -1
  447. package/lib/typescript/src/types/events.d.ts +85 -0
  448. package/lib/typescript/src/types/events.d.ts.map +1 -1
  449. package/lib/typescript/src/utils/textInputState.d.ts +24 -0
  450. package/lib/typescript/src/utils/textInputState.d.ts.map +1 -0
  451. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts +1 -1
  452. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts.map +1 -1
  453. package/lib/typescript/src/web/parseMarkdown.d.ts +1 -1
  454. package/lib/typescript/src/web/parseMarkdown.d.ts.map +1 -1
  455. package/lib/typescript/src/web/renderers/InlineRenderers.d.ts.map +1 -1
  456. package/lib/typescript/src/web/renderers/ListRenderers.d.ts.map +1 -1
  457. package/lib/typescript/src/web/renderers/index.d.ts +2 -1
  458. package/lib/typescript/src/web/renderers/index.d.ts.map +1 -1
  459. package/lib/typescript/src/web/styles.d.ts +2 -1
  460. package/lib/typescript/src/web/styles.d.ts.map +1 -1
  461. package/lib/typescript/src/web/types.d.ts +10 -2
  462. package/lib/typescript/src/web/types.d.ts.map +1 -1
  463. package/lib/typescript/src/web/utils.d.ts +4 -0
  464. package/lib/typescript/src/web/utils.d.ts.map +1 -1
  465. package/package.json +36 -9
  466. package/postinstall.mjs +131 -0
  467. package/ratex-version.json +21 -0
  468. package/src/EnrichedMarkdownNativeComponent.ts +203 -1
  469. package/src/EnrichedMarkdownTextInput.tsx +159 -8
  470. package/src/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
  471. package/src/EnrichedMarkdownTextNativeComponent.ts +204 -1
  472. package/src/headingDefaults.ts +21 -0
  473. package/src/index.tsx +15 -0
  474. package/src/index.web.tsx +6 -1
  475. package/src/jest/index.tsx +236 -0
  476. package/src/native/EnrichedMarkdownText.tsx +260 -11
  477. package/src/normalizeMarkdownStyle.ts +117 -16
  478. package/src/normalizeMarkdownStyle.web.ts +76 -15
  479. package/src/normalizeMarkdownTextInputStyle.ts +110 -35
  480. package/src/normalizeMenuItem.ts +1 -1
  481. package/src/types/MarkdownStyle.ts +125 -5
  482. package/src/types/MarkdownStyleInternal.ts +51 -0
  483. package/src/types/MarkdownTextProps.ts +215 -10
  484. package/src/types/MarkdownTextProps.web.ts +62 -1
  485. package/src/types/events.ts +90 -0
  486. package/src/utils/textInputState.ts +35 -0
  487. package/src/web/EnrichedMarkdownText.tsx +26 -5
  488. package/src/web/parseMarkdown.ts +6 -2
  489. package/src/web/renderers/InlineRenderers.tsx +116 -3
  490. package/src/web/renderers/ListRenderers.tsx +14 -2
  491. package/src/web/renderers/index.tsx +6 -2
  492. package/src/web/styles.ts +114 -5
  493. package/src/web/types.ts +10 -1
  494. package/src/web/utils.ts +9 -0
  495. package/src/web/wasm/md4c.js +0 -0
  496. package/vendor-grammars.mjs +511 -0
  497. package/vendor-ratex.mjs +173 -0
  498. package/app.plugin.js +0 -2
  499. package/plugin/build/withAndroidMath.js +0 -19
  500. package/plugin/build/withIosMath.js +0 -28
  501. package/plugin/build/withReactNativeEnrichedMarkdown.js +0 -11
  502. package/plugin/src/withAndroidMath.ts +0 -24
  503. package/plugin/src/withIosMath.ts +0 -35
  504. package/plugin/src/withReactNativeEnrichedMarkdown.ts +0 -17
  505. package/plugin/tsconfig.build.json +0 -16
@@ -5,6 +5,7 @@
5
5
  // Attribute constants for identifying blockquote segments in text storage
6
6
  NSString *const BlockquoteDepthAttributeName = @"BlockquoteDepth";
7
7
  NSString *const BlockquoteBackgroundColorAttributeName = @"BlockquoteBackgroundColor";
8
+ NSString *const BlockquoteSpacerAttributeName = @"BlockquoteSpacer";
8
9
 
9
10
  @implementation BlockquoteBorder {
10
11
  StyleConfig *_config;
@@ -20,7 +21,15 @@ NSString *const BlockquoteBackgroundColorAttributeName = @"BlockquoteBackgroundC
20
21
 
21
22
  /**
22
23
  * Main drawing entry point called by the LayoutManager.
23
- * Iterates through line fragments to draw backgrounds and borders for nested blockquotes.
24
+ * Collects contiguous blockquote regions and draws each as one rounded box:
25
+ * background fill first, then the vertical borders clipped to the box shape.
26
+ * When a border radius is set, each nested quote's stripes are additionally
27
+ * clipped to that quote's own rounded box, mirroring per-element CSS
28
+ * border-radius on web.
29
+ * Regions are discovered by scanning only the drawn character range; regions
30
+ * touching its edges are extended run-by-run to their true boundaries, so the
31
+ * cost scales with the visible text plus the intersecting quotes rather than
32
+ * the whole document.
24
33
  */
25
34
  - (void)drawBordersForGlyphRange:(NSRange)glyphsToShow
26
35
  layoutManager:(NSLayoutManager *)layoutManager
@@ -32,66 +41,254 @@ NSString *const BlockquoteBackgroundColorAttributeName = @"BlockquoteBackgroundC
32
41
  return;
33
42
  }
34
43
 
44
+ NSRange charRange = [layoutManager characterRangeForGlyphRange:glyphsToShow actualGlyphRange:NULL];
45
+ if (charRange.location == NSNotFound || charRange.length == 0) {
46
+ return;
47
+ }
48
+
49
+ NSMutableArray<NSValue *> *regions = [NSMutableArray array];
50
+ __block NSRange currentRegion = NSMakeRange(NSNotFound, 0);
51
+ [textStorage enumerateAttribute:BlockquoteDepthAttributeName
52
+ inRange:charRange
53
+ options:0
54
+ usingBlock:^(id value, NSRange range, BOOL *stop) {
55
+ if (!value) {
56
+ if (currentRegion.location != NSNotFound) {
57
+ [regions addObject:[NSValue valueWithRange:currentRegion]];
58
+ currentRegion = NSMakeRange(NSNotFound, 0);
59
+ }
60
+ return;
61
+ }
62
+ currentRegion =
63
+ currentRegion.location == NSNotFound ? range : NSUnionRange(currentRegion, range);
64
+ }];
65
+ if (currentRegion.location != NSNotFound) {
66
+ [regions addObject:[NSValue valueWithRange:currentRegion]];
67
+ }
68
+
69
+ if (regions.count == 0) {
70
+ return;
71
+ }
72
+
73
+ NSRange firstRegion = regions.firstObject.rangeValue;
74
+ if (firstRegion.location == charRange.location) {
75
+ while (firstRegion.location > 0) {
76
+ NSRange runRange;
77
+ if (![textStorage attribute:BlockquoteDepthAttributeName
78
+ atIndex:firstRegion.location - 1
79
+ effectiveRange:&runRange]) {
80
+ break;
81
+ }
82
+ firstRegion = NSUnionRange(firstRegion, runRange);
83
+ }
84
+ regions[0] = [NSValue valueWithRange:firstRegion];
85
+ }
86
+
87
+ NSRange lastRegion = regions.lastObject.rangeValue;
88
+ if (NSMaxRange(lastRegion) == NSMaxRange(charRange)) {
89
+ while (NSMaxRange(lastRegion) < textStorage.length) {
90
+ NSRange runRange;
91
+ if (![textStorage attribute:BlockquoteDepthAttributeName
92
+ atIndex:NSMaxRange(lastRegion)
93
+ effectiveRange:&runRange]) {
94
+ break;
95
+ }
96
+ lastRegion = NSUnionRange(lastRegion, runRange);
97
+ }
98
+ regions[regions.count - 1] = [NSValue valueWithRange:lastRegion];
99
+ }
100
+
101
+ for (NSValue *value in regions) {
102
+ [self drawBlockquoteRegion:value.rangeValue layoutManager:layoutManager textContainer:textContainer atPoint:origin];
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Groups the depth runs of a region into nested quote boxes: for each level
108
+ * >= 1, a box is a maximal contiguous stretch where depth >= level (a nested
109
+ * quote's own range). Outputs parallel arrays of ranges and levels.
110
+ */
111
+ static void collectNestedBoxes(NSArray<NSValue *> *runRanges, NSArray<NSNumber *> *runDepths,
112
+ NSMutableArray<NSValue *> *boxRanges, NSMutableArray<NSNumber *> *boxLevels)
113
+ {
114
+ NSInteger maxDepth = 0;
115
+ for (NSNumber *depth in runDepths) {
116
+ maxDepth = MAX(maxDepth, depth.integerValue);
117
+ }
118
+
119
+ for (NSInteger level = 1; level <= maxDepth; level++) {
120
+ NSRange current = NSMakeRange(NSNotFound, 0);
121
+ for (NSUInteger i = 0; i < runRanges.count; i++) {
122
+ if (runDepths[i].integerValue >= level) {
123
+ NSRange runRange = runRanges[i].rangeValue;
124
+ current = current.location == NSNotFound ? runRange : NSUnionRange(current, runRange);
125
+ } else if (current.location != NSNotFound) {
126
+ [boxRanges addObject:[NSValue valueWithRange:current]];
127
+ [boxLevels addObject:@(level)];
128
+ current = NSMakeRange(NSNotFound, 0);
129
+ }
130
+ }
131
+ if (current.location != NSNotFound) {
132
+ [boxRanges addObject:[NSValue valueWithRange:current]];
133
+ [boxLevels addObject:@(level)];
134
+ }
135
+ }
136
+ }
137
+
138
+ - (void)drawBlockquoteRegion:(NSRange)region
139
+ layoutManager:(NSLayoutManager *)layoutManager
140
+ textContainer:(NSTextContainer *)textContainer
141
+ atPoint:(CGPoint)origin
142
+ {
143
+ NSTextStorage *textStorage = layoutManager.textStorage;
144
+
35
145
  // Cache configuration values to minimize pointer chasing and method lookups in the loop
36
146
  StyleConfig *c = _config;
37
147
  CGFloat borderWidth = c.blockquoteBorderWidth;
38
148
  CGFloat gapWidth = c.blockquoteGapWidth;
39
149
  CGFloat levelSpacing = borderWidth + gapWidth;
150
+ CGFloat borderRadius = c.blockquoteBorderRadius;
40
151
  CGFloat containerWidth = textContainer.size.width;
41
152
  RCTUIColor *defaultBgColor = c.blockquoteBackgroundColor;
42
153
  RCTUIColor *borderColor = c.blockquoteBorderColor;
43
154
 
44
- UIBezierPath *borderPath = [UIBezierPath bezierPath];
45
-
46
- [layoutManager
47
- enumerateLineFragmentsForGlyphRange:glyphsToShow
48
- usingBlock:^(CGRect rect, CGRect usedRect, NSTextContainer *container,
49
- NSRange glyphRange, BOOL *stop) {
50
- // Map the glyph range back to character indices to retrieve attributes
51
- NSRange charRange = [layoutManager characterRangeForGlyphRange:glyphRange
52
- actualGlyphRange:NULL];
53
- if (charRange.location == NSNotFound || charRange.length == 0) {
54
- return;
55
- }
56
-
57
- // Perform a single attribute lookup for the current line fragment
58
- NSDictionary *attrs = [textStorage attributesAtIndex:charRange.location
59
- effectiveRange:NULL];
60
- NSNumber *depthNum = attrs[BlockquoteDepthAttributeName];
61
-
62
- // If no depth is found, this fragment is not part of a blockquote
63
- if (!depthNum) {
64
- return;
65
- }
66
-
67
- NSInteger depth = [depthNum integerValue];
68
- CGFloat baseY = origin.y + rect.origin.y;
69
- BOOL isRTL = ENRMParagraphIsRTL(attrs[NSParagraphStyleAttributeName]);
70
-
71
- // 1. Draw Background (Painter's algorithm: draw backgrounds before borders)
72
- RCTUIColor *bgColor = attrs[BlockquoteBackgroundColorAttributeName] ?: defaultBgColor;
73
- if (bgColor && bgColor != [RCTUIColor clearColor]) {
74
- CGContextRef ctx = UIGraphicsGetCurrentContext();
75
- [bgColor setFill];
76
- CGContextFillRect(ctx,
77
- CGRectMake(origin.x, baseY, containerWidth, rect.size.height));
78
- }
79
-
80
- // 2. Aggregate vertical borders into the batch path
81
- for (NSInteger level = 0; level <= depth; level++) {
82
- CGFloat borderX =
83
- isRTL ? origin.x + containerWidth - borderWidth - (levelSpacing * level)
84
- : origin.x + (levelSpacing * level);
85
- CGRect borderRect = CGRectMake(borderX, baseY, borderWidth, rect.size.height);
86
- UIBezierPathAppendPath(borderPath, [UIBezierPath bezierPathWithRect:borderRect]);
87
- }
88
- }];
89
-
90
- // 3. Perform a single batch fill for all borders
91
- if (!borderPath.isEmpty) {
92
- [borderColor setFill];
93
- [borderPath fill];
155
+ NSRange glyphRange = [layoutManager glyphRangeForCharacterRange:region actualCharacterRange:NULL];
156
+ CGRect blockRect = [layoutManager boundingRectForGlyphRange:glyphRange inTextContainer:textContainer];
157
+ if (CGRectIsEmpty(blockRect)) {
158
+ return;
159
+ }
160
+
161
+ blockRect.origin.x = origin.x;
162
+ blockRect.origin.y += origin.y;
163
+ blockRect.size.width = containerWidth;
164
+
165
+ BOOL isLastBlockquote = (NSMaxRange(region) == textStorage.length);
166
+ if (isLastBlockquote) {
167
+ blockRect.size.height += c.blockquotePadding;
168
+ }
169
+
170
+ NSMutableArray<NSValue *> *boxRanges = [NSMutableArray array];
171
+ NSMutableArray<NSNumber *> *boxLevels = [NSMutableArray array];
172
+ NSMutableArray<UIBezierPath *> *boxStripePaths = [NSMutableArray array];
173
+ if (borderRadius > 0) {
174
+ NSMutableArray<NSValue *> *runRanges = [NSMutableArray array];
175
+ NSMutableArray<NSNumber *> *runDepths = [NSMutableArray array];
176
+ [textStorage enumerateAttribute:BlockquoteDepthAttributeName
177
+ inRange:region
178
+ options:0
179
+ usingBlock:^(id value, NSRange range, BOOL *stop) {
180
+ if (!value) {
181
+ return;
182
+ }
183
+ [runRanges addObject:[NSValue valueWithRange:range]];
184
+ [runDepths addObject:value];
185
+ }];
186
+ collectNestedBoxes(runRanges, runDepths, boxRanges, boxLevels);
187
+ for (NSUInteger i = 0; i < boxRanges.count; i++) {
188
+ [boxStripePaths addObject:[UIBezierPath bezierPath]];
189
+ }
190
+ }
191
+
192
+ CGContextRef ctx = UIGraphicsGetCurrentContext();
193
+ CGContextSaveGState(ctx);
194
+ {
195
+ UIBezierPath *boxPath = UIBezierPathWithRoundedRect(blockRect, MAX(0, borderRadius));
196
+ [boxPath addClip];
197
+
198
+ // 1. Draw Background (Painter's algorithm: draw backgrounds before borders)
199
+ RCTUIColor *bgColor = [textStorage attribute:BlockquoteBackgroundColorAttributeName
200
+ atIndex:region.location
201
+ effectiveRange:NULL]
202
+ ?: defaultBgColor;
203
+ if (bgColor && bgColor != [RCTUIColor clearColor]) {
204
+ [bgColor setFill];
205
+ CGContextFillRect(ctx, blockRect);
206
+ }
207
+
208
+ // 2. Aggregate vertical borders into batch paths; level-0 stripes are
209
+ // rounded by the region clip, nested stripes by their own box clip below
210
+ UIBezierPath *borderPath = [UIBezierPath bezierPath];
211
+ [layoutManager
212
+ enumerateLineFragmentsForGlyphRange:glyphRange
213
+ usingBlock:^(CGRect rect, CGRect usedRect, NSTextContainer *container,
214
+ NSRange lineGlyphRange, BOOL *stop) {
215
+ NSRange lineCharRange = [layoutManager characterRangeForGlyphRange:lineGlyphRange
216
+ actualGlyphRange:NULL];
217
+ if (lineCharRange.location == NSNotFound || lineCharRange.length == 0) {
218
+ return;
219
+ }
220
+
221
+ NSDictionary *attrs = [textStorage attributesAtIndex:lineCharRange.location
222
+ effectiveRange:NULL];
223
+ NSNumber *depthNum = attrs[BlockquoteDepthAttributeName];
224
+
225
+ if (!depthNum) {
226
+ return;
227
+ }
228
+
229
+ NSInteger depth = [depthNum integerValue];
230
+ CGFloat baseY = origin.y + rect.origin.y;
231
+ CGFloat lineHeight = rect.size.height;
232
+ BOOL isLastLine = NSMaxRange(lineGlyphRange) == NSMaxRange(glyphRange);
233
+ if (isLastBlockquote && isLastLine) {
234
+ lineHeight += c.blockquotePadding;
235
+ }
236
+ BOOL isRTL = ENRMParagraphIsRTL(attrs[NSParagraphStyleAttributeName]);
237
+
238
+ for (NSInteger level = 0; level <= depth; level++) {
239
+ CGFloat borderX =
240
+ isRTL ? origin.x + containerWidth - borderWidth - (levelSpacing * level)
241
+ : origin.x + (levelSpacing * level);
242
+ CGRect borderRect = CGRectMake(borderX, baseY, borderWidth, lineHeight);
243
+
244
+ UIBezierPath *target = borderPath;
245
+ for (NSUInteger b = 0; b < boxRanges.count; b++) {
246
+ if (boxLevels[b].integerValue == level &&
247
+ NSLocationInRange(lineCharRange.location, boxRanges[b].rangeValue)) {
248
+ target = boxStripePaths[b];
249
+ break;
250
+ }
251
+ }
252
+ UIBezierPathAppendPath(target, [UIBezierPath bezierPathWithRect:borderRect]);
253
+ }
254
+ }];
255
+
256
+ // 3. Perform a single batch fill for the root-level borders
257
+ if (!borderPath.isEmpty) {
258
+ [borderColor setFill];
259
+ [borderPath fill];
260
+ }
261
+
262
+ // 4. Nested stripes: clip each to its own quote's rounded box (the clips
263
+ // compose with the still-active region clip)
264
+ for (NSUInteger b = 0; b < boxRanges.count; b++) {
265
+ UIBezierPath *stripes = boxStripePaths[b];
266
+ if (stripes.isEmpty) {
267
+ continue;
268
+ }
269
+
270
+ NSRange boxRange = boxRanges[b].rangeValue;
271
+ NSRange boxGlyphRange = [layoutManager glyphRangeForCharacterRange:boxRange actualCharacterRange:NULL];
272
+ CGRect boxRect = [layoutManager boundingRectForGlyphRange:boxGlyphRange inTextContainer:textContainer];
273
+ if (CGRectIsEmpty(boxRect)) {
274
+ continue;
275
+ }
276
+
277
+ NSDictionary *boxAttrs = [textStorage attributesAtIndex:boxRange.location effectiveRange:NULL];
278
+ BOOL boxRTL = ENRMParagraphIsRTL(boxAttrs[NSParagraphStyleAttributeName]);
279
+ CGFloat leadingInset = levelSpacing * boxLevels[b].integerValue;
280
+ boxRect.origin.x = boxRTL ? origin.x : origin.x + leadingInset;
281
+ boxRect.origin.y += origin.y;
282
+ boxRect.size.width = containerWidth - leadingInset;
283
+
284
+ CGContextSaveGState(ctx);
285
+ [UIBezierPathWithRoundedRect(boxRect, borderRadius) addClip];
286
+ [borderColor setFill];
287
+ [stripes fill];
288
+ CGContextRestoreGState(ctx);
289
+ }
94
290
  }
291
+ CGContextRestoreGState(ctx);
95
292
  }
96
293
 
97
- @end
294
+ @end
@@ -1,4 +1,5 @@
1
1
  #import "CodeBackground.h"
2
+ #import "ENRMChipDrawing.h"
2
3
  #import "ENRMUIKit.h"
3
4
  #import "RenderContext.h"
4
5
 
@@ -116,71 +117,8 @@ static const CGFloat kCodeBackgroundBorderWidth = 0.5;
116
117
  isFirst:(BOOL)isFirst
117
118
  isLast:(BOOL)isLast
118
119
  {
119
- UIBezierPath *path = [self pathForRect:rect isFirst:isFirst isLast:isLast];
120
- [backgroundColor setFill];
121
- [path fill];
122
-
123
- if (borderColor) {
124
- [borderColor setStroke];
125
- UIBezierPath *strokePath =
126
- (isFirst && isLast) ? path : [self openBorderPathForRect:rect isFirst:isFirst isLast:isLast];
127
- strokePath.lineWidth = kCodeBackgroundBorderWidth;
128
- BezierPathSetRoundStyle(strokePath);
129
- [strokePath stroke];
130
- }
131
- }
132
-
133
- - (UIBezierPath *)pathForRect:(CGRect)rect isFirst:(BOOL)isFirst isLast:(BOOL)isLast
134
- {
135
- #if !TARGET_OS_OSX
136
- UIRectCorner corners = 0;
137
- if (isFirst)
138
- corners |= (UIRectCornerTopLeft | UIRectCornerBottomLeft);
139
- if (isLast)
140
- corners |= (UIRectCornerTopRight | UIRectCornerBottomRight);
141
-
142
- return [UIBezierPath bezierPathWithRoundedRect:rect
143
- byRoundingCorners:corners
144
- cornerRadii:CGSizeMake(kCodeBackgroundCornerRadius, kCodeBackgroundCornerRadius)];
145
- #else
146
- // NSBezierPath doesn't support per-corner rounding — use uniform corner radius
147
- CGFloat cornerRadius = (isFirst || isLast) ? kCodeBackgroundCornerRadius : 0;
148
- return UIBezierPathWithRoundedRect(rect, cornerRadius);
149
- #endif
150
- }
151
-
152
- - (UIBezierPath *)openBorderPathForRect:(CGRect)rect isFirst:(BOOL)isFirst isLast:(BOOL)isLast
153
- {
154
- UIBezierPath *path = [UIBezierPath bezierPath];
155
- CGFloat r = kCodeBackgroundCornerRadius;
156
- CGFloat inset = kCodeBackgroundBorderWidth / 2.0;
157
- CGRect insetRect = CGRectInset(rect, inset, inset);
158
-
159
- if (isFirst) {
160
- [path moveToPoint:CGPointMake(CGRectGetMaxX(rect), insetRect.origin.y)];
161
- BezierPathAddLine(path, CGPointMake(insetRect.origin.x + r, insetRect.origin.y));
162
- BezierPathAddQuadCurve(path, CGPointMake(insetRect.origin.x, insetRect.origin.y + r),
163
- CGPointMake(insetRect.origin.x, insetRect.origin.y));
164
- BezierPathAddLine(path, CGPointMake(insetRect.origin.x, CGRectGetMaxY(insetRect) - r));
165
- BezierPathAddQuadCurve(path, CGPointMake(insetRect.origin.x + r, CGRectGetMaxY(insetRect)),
166
- CGPointMake(insetRect.origin.x, CGRectGetMaxY(insetRect)));
167
- BezierPathAddLine(path, CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(insetRect)));
168
- } else if (isLast) {
169
- [path moveToPoint:CGPointMake(rect.origin.x, insetRect.origin.y)];
170
- BezierPathAddLine(path, CGPointMake(CGRectGetMaxX(insetRect) - r, insetRect.origin.y));
171
- BezierPathAddQuadCurve(path, CGPointMake(CGRectGetMaxX(insetRect), insetRect.origin.y + r),
172
- CGPointMake(CGRectGetMaxX(insetRect), insetRect.origin.y));
173
- BezierPathAddLine(path, CGPointMake(CGRectGetMaxX(insetRect), CGRectGetMaxY(insetRect) - r));
174
- BezierPathAddQuadCurve(path, CGPointMake(CGRectGetMaxX(insetRect) - r, CGRectGetMaxY(insetRect)),
175
- CGPointMake(CGRectGetMaxX(insetRect), CGRectGetMaxY(insetRect)));
176
- BezierPathAddLine(path, CGPointMake(rect.origin.x, CGRectGetMaxY(insetRect)));
177
- } else {
178
- [path moveToPoint:CGPointMake(rect.origin.x, insetRect.origin.y)];
179
- BezierPathAddLine(path, CGPointMake(CGRectGetMaxX(rect), insetRect.origin.y));
180
- [path moveToPoint:CGPointMake(rect.origin.x, CGRectGetMaxY(insetRect))];
181
- BezierPathAddLine(path, CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(insetRect)));
182
- }
183
- return path;
120
+ ENRMDrawChipFragment(rect, backgroundColor, borderColor, kCodeBackgroundBorderWidth, kCodeBackgroundCornerRadius,
121
+ isFirst, isLast, NO);
184
122
  }
185
123
 
186
124
  #pragma mark - Helpers
@@ -3,6 +3,11 @@
3
3
  #import "LastElementUtils.h"
4
4
  #import "StyleConfig.h"
5
5
 
6
+ // Draws the commonmark-flavor code block box behind the text view's glyph
7
+ // runs. The visual conventions (half-stroke border inset, corner radius
8
+ // handling) must stay in sync with the whole-rect box the github flavor
9
+ // draws in ENRMCodeBlockContainerView's drawRect:.
10
+
6
11
  @implementation CodeBlockBackground {
7
12
  StyleConfig *_config;
8
13
  }
@@ -53,9 +58,18 @@
53
58
  if (CGRectIsEmpty(blockRect))
54
59
  return;
55
60
 
56
- blockRect.origin.x = origin.x;
61
+ NSNumber *indentAttr = [layoutManager.textStorage attribute:CodeBlockIndentAttributeName
62
+ atIndex:range.location
63
+ effectiveRange:NULL];
64
+ CGFloat indent = [indentAttr doubleValue];
65
+
66
+ CGFloat availableWidth = textContainer.size.width - indent;
67
+ if (availableWidth <= 0)
68
+ return;
69
+
70
+ blockRect.origin.x = origin.x + indent;
57
71
  blockRect.origin.y += origin.y;
58
- blockRect.size.width = textContainer.size.width;
72
+ blockRect.size.width = availableWidth;
59
73
 
60
74
  // We extend the background specifically to cover the bottom padding spacer,
61
75
  // excluding any additional marginBottom applied via measurement.
@@ -0,0 +1,65 @@
1
+ #pragma once
2
+
3
+ #include <CoreGraphics/CGGeometry.h>
4
+ #include <atomic>
5
+ #include <cstdint>
6
+ #include <cstring>
7
+
8
+ /**
9
+ * Lock-free size mailbox (issue #550).
10
+ *
11
+ * `measureContent` may run on the JS/layout thread while React Native holds
12
+ * the ShadowTree revision mutex (`preventShadowTreeCommitExhaustion` re-runs
13
+ * the entire commit — layout included — under `revisionMutexRecursive_` after
14
+ * three failed optimistic commits). A main-thread committer (e.g. Reanimated)
15
+ * can already be blocked on that same mutex, so any `dispatch_sync` to main
16
+ * from the measure path can deadlock: JS waits for main, main waits for the
17
+ * mutex JS holds. iOS kills the frozen app ~60s later (watchdog 0x8BADF00D).
18
+ *
19
+ * Reading `view.bounds` from a background thread is not safe either, so the
20
+ * component view *publishes* its last committed size here (from
21
+ * `updateLayoutMetrics:`, always on main) and the measure path *loads* it
22
+ * wait-free from any thread.
23
+ *
24
+ * Both dimensions are packed as IEEE-754 floats into one `uint64_t` so a
25
+ * single lock-free atomic covers the pair — a reader can never observe a new
26
+ * width with an old height (no torn reads). Relaxed memory ordering suffices:
27
+ * the value is self-contained and no other memory is published through it.
28
+ */
29
+ class ENRMAtomicSize {
30
+ public:
31
+ void store(CGSize size)
32
+ {
33
+ bits_.store(pack(size), std::memory_order_relaxed);
34
+ }
35
+
36
+ CGSize load() const
37
+ {
38
+ return unpack(bits_.load(std::memory_order_relaxed));
39
+ }
40
+
41
+ private:
42
+ static uint64_t pack(CGSize size)
43
+ {
44
+ float width = (float)size.width;
45
+ float height = (float)size.height;
46
+ uint32_t widthBits;
47
+ uint32_t heightBits;
48
+ memcpy(&widthBits, &width, sizeof(widthBits));
49
+ memcpy(&heightBits, &height, sizeof(heightBits));
50
+ return ((uint64_t)widthBits << 32) | heightBits;
51
+ }
52
+
53
+ static CGSize unpack(uint64_t bits)
54
+ {
55
+ uint32_t widthBits = (uint32_t)(bits >> 32);
56
+ uint32_t heightBits = (uint32_t)bits;
57
+ float width;
58
+ float height;
59
+ memcpy(&width, &widthBits, sizeof(width));
60
+ memcpy(&height, &heightBits, sizeof(height));
61
+ return CGSizeMake(width, height);
62
+ }
63
+
64
+ std::atomic<uint64_t> bits_{0};
65
+ };
@@ -0,0 +1,66 @@
1
+ #pragma once
2
+ #import "ENRMUIKit.h"
3
+ #include <TargetConditionals.h>
4
+
5
+ NS_ASSUME_NONNULL_BEGIN
6
+
7
+ /// Selection-menu options that table, math and code block views need for their
8
+ /// own long-press menus. Every field is phrased so that the zero value keeps the
9
+ /// legacy behavior, so a block view that has not received options yet behaves
10
+ /// exactly as before.
11
+ typedef struct {
12
+ // `selectionMenuConfig.copy.enabled == false`.
13
+ BOOL copyHidden;
14
+ // `selectionMenuConfig.copy.format == 'markdown'`: the Copy item writes the
15
+ // block's Markdown instead of its raw content.
16
+ BOOL copyWritesMarkdown;
17
+ // `selectionMenuConfig.copyAsMarkdown.enabled == false`.
18
+ BOOL copyAsMarkdownHidden;
19
+ // `selectionMenuConfig.codeBlockCopyButton.enabled == false`.
20
+ BOOL copyButtonHidden;
21
+ // JS `onCopy` is set: the Copy item hands the block's content to the view's
22
+ // `onCopyRequest` instead of writing the pasteboard.
23
+ BOOL interceptCopy;
24
+ } ENRMBlockMenuOptions;
25
+
26
+ /// Receives an intercepted block Copy: the block's Markdown and its raw content.
27
+ typedef void (^ENRMBlockCopyRequestBlock)(NSString *markdown, NSString *text);
28
+
29
+ #if !TARGET_OS_OSX
30
+ /// Builds the long-press menu shared by the table, math and code block views.
31
+ /// Returns nil when no item is left — nil is how UIKit suppresses a context
32
+ /// menu, whereas an empty menu would still lift the view. `requestCopy` replaces
33
+ /// the Copy item's handler when `options.interceptCopy` is set.
34
+ static inline UIContextMenuConfiguration *_Nullable ENRMBlockContextMenuConfiguration(
35
+ ENRMBlockMenuOptions options, NSString *_Nullable copyLabel, NSString *_Nullable copyAsMarkdownLabel,
36
+ void (^copyRaw)(void), void (^copyMarkdown)(void), void (^_Nullable requestCopy)(void))
37
+ {
38
+ if (options.copyHidden && options.copyAsMarkdownHidden) {
39
+ return nil;
40
+ }
41
+ void (^copyHandler)(void) = (options.interceptCopy && requestCopy) ? requestCopy
42
+ : options.copyWritesMarkdown ? copyMarkdown
43
+ : copyRaw;
44
+ return [UIContextMenuConfiguration
45
+ configurationWithIdentifier:nil
46
+ previewProvider:nil
47
+ actionProvider:^UIMenu *(NSArray<UIMenuElement *> *suggestedActions) {
48
+ NSMutableArray<UIMenuElement *> *children = [NSMutableArray arrayWithCapacity:2];
49
+ if (!options.copyHidden) {
50
+ [children addObject:[UIAction actionWithTitle:copyLabel ?: @""
51
+ image:[RCTUIImage systemImageNamed:@"doc.on.doc"]
52
+ identifier:nil
53
+ handler:^(__kindof UIAction *action) { copyHandler(); }]];
54
+ }
55
+ if (!options.copyAsMarkdownHidden) {
56
+ [children addObject:[UIAction actionWithTitle:copyAsMarkdownLabel ?: @""
57
+ image:[RCTUIImage systemImageNamed:@"doc.text"]
58
+ identifier:nil
59
+ handler:^(__kindof UIAction *action) { copyMarkdown(); }]];
60
+ }
61
+ return [UIMenu menuWithTitle:@"" children:children];
62
+ }];
63
+ }
64
+ #endif
65
+
66
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,24 @@
1
+ #pragma once
2
+ #import "ENRMUIKit.h"
3
+
4
+ NS_ASSUME_NONNULL_BEGIN
5
+
6
+ #ifdef __cplusplus
7
+ extern "C" {
8
+ #endif
9
+
10
+ /// Fills (and optionally strokes) one line fragment of an inline "chip" — the
11
+ /// rounded background shared by inline code and link chips. For a chip that
12
+ /// wraps, only the outer ends are rounded (`isFirst` / `isLast`) and the border
13
+ /// stays open where the fragment is cut.
14
+ ///
15
+ /// `strokeInset` keeps a closed border inside `rect` (link chips); otherwise it
16
+ /// is centered on the edge (inline code, kept for pixel parity).
17
+ void ENRMDrawChipFragment(CGRect rect, RCTUIColor *_Nullable backgroundColor, RCTUIColor *_Nullable borderColor,
18
+ CGFloat borderWidth, CGFloat cornerRadius, BOOL isFirst, BOOL isLast, BOOL strokeInset);
19
+
20
+ #ifdef __cplusplus
21
+ }
22
+ #endif
23
+
24
+ NS_ASSUME_NONNULL_END