react-native-enriched-markdown-scaffold 0.7.4-scaffold.8 → 1.0.2-scaffold.1

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 (469) hide show
  1. package/README.md +54 -8
  2. package/ReactNativeEnrichedMarkdown.podspec +82 -73
  3. package/android/build.gradle +191 -1
  4. package/android/consumer-rules.pro +1 -1
  5. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +9 -0
  6. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +3 -0
  7. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerDelegate.java +27 -0
  8. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerInterface.java +9 -0
  9. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +9 -0
  10. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +3 -0
  11. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
  12. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
  13. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +40 -0
  14. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +839 -23
  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 +175 -11
  18. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +17 -0
  19. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +50 -0
  20. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +48 -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 +42 -0
  23. package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +82 -4
  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/input/EnrichedMarkdownTextInputManager.kt +62 -4
  26. package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +911 -460
  27. package/android/src/main/java/com/swmansion/enriched/markdown/input/MarkdownClipboard.kt +42 -0
  28. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/BlockEditCoordinator.kt +196 -0
  29. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/ClipboardCoordinator.kt +73 -0
  30. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditContext.kt +19 -0
  31. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditPipeline.kt +248 -0
  32. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditSession.kt +52 -0
  33. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/InputConnectionWrapper.kt +101 -7
  34. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/LinkCoordinator.kt +69 -0
  35. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MarkdownTextWatcher.kt +3 -3
  36. package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MentionCoordinator.kt +118 -0
  37. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeStateEvent.kt +26 -0
  38. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnContextMenuItemPressEvent.kt +26 -0
  39. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnInputKeyPressEvent.kt +24 -0
  40. package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnPasteEvent.kt +24 -0
  41. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockStore.kt +254 -0
  42. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockSyntaxSentinel.kt +69 -0
  43. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/FormattingStore.kt +80 -87
  44. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputFormatter.kt +109 -1
  45. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +180 -27
  46. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/MarkdownSerializer.kt +167 -38
  47. package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/RangeEditAdjustment.kt +149 -0
  48. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputEventEmitter.kt +66 -5
  49. package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +7 -2
  50. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockRange.kt +27 -0
  51. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockType.kt +48 -0
  52. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/FormattingRange.kt +9 -4
  53. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/InputFormatterStyle.kt +39 -2
  54. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathAtom.kt +20 -0
  55. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +1 -1
  56. package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MutableRangeBounds.kt +11 -0
  57. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputBulletSpan.kt +82 -0
  58. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputHeadingSpan.kt +58 -0
  59. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputListItemSpacingSpan.kt +37 -0
  60. package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputOrderedListMarkerSpan.kt +63 -0
  61. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/BlockHandler.kt +54 -0
  62. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/HeadingBlockHandler.kt +27 -0
  63. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/OrderedListBlockHandler.kt +38 -0
  64. package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/UnorderedListBlockHandler.kt +37 -0
  65. package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +8 -26
  66. package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +1 -0
  67. package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +1 -0
  68. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +9 -2
  69. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +100 -12
  70. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +16 -1
  71. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +4 -0
  72. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +2 -1
  73. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +74 -18
  74. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +43 -4
  75. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +9 -1
  76. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SoftBreakRenderer.kt +16 -0
  77. package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +30 -27
  78. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +24 -0
  79. package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +174 -24
  80. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +27 -3
  81. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +13 -16
  82. package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
  83. package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +1 -1
  84. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +182 -46
  85. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListItemSpacingSpan.kt +33 -0
  86. package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListMarkerAnchorSpan.kt +38 -0
  87. package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +2 -0
  88. package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -1
  89. package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +3 -2
  90. package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +3 -2
  91. package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +6 -0
  92. package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +26 -0
  93. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +7 -1
  94. package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +4 -1
  95. package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +13 -4
  96. package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +6 -0
  97. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockHighlighter.kt +90 -0
  98. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockNode.kt +57 -0
  99. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/FeatureFlags.kt +1 -0
  100. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownSegment.kt +9 -0
  101. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +33 -7
  102. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/ReadableMapExtensions.kt +3 -0
  103. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/RenderedSegment.kt +10 -0
  104. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentSignature.kt +1 -0
  105. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/StreamingMarkdownFilter.kt +83 -5
  106. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +4 -0
  107. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +74 -44
  108. package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/PasteTextUtils.kt +20 -0
  109. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +26 -3
  110. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +22 -9
  111. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/LocalImageLoader.kt +161 -0
  112. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/TextPaintExtensions.kt +23 -0
  113. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/CheckboxTouchHelper.kt +7 -0
  114. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +41 -21
  115. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt +15 -8
  116. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLongPressMovementMethod.kt +58 -27
  117. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +19 -2
  118. package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +388 -0
  119. package/android/src/main/java/com/swmansion/enriched/markdown/views/ContextMenuPopup.kt +9 -6
  120. package/android/src/main/java/com/swmansion/enriched/markdown/views/CopyGlyph.kt +101 -0
  121. package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +32 -5
  122. package/android/src/main/jni/CMakeLists.txt +53 -0
  123. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.cpp +10 -0
  124. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +11 -2
  125. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +10 -0
  126. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +12 -2
  127. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.cpp +9 -0
  128. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.h +24 -0
  129. package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +16 -0
  130. package/android/src/math/java/com/swmansion/enriched/markdown/input/math/MathChipControllerImpl.kt +21 -4
  131. package/android/src/math/java/com/swmansion/enriched/markdown/renderer/MathInlineRenderer.kt +7 -2
  132. package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +1 -1
  133. package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +2 -0
  134. package/cpp/highlight/CodeBlockHighlighter.cpp +284 -0
  135. package/cpp/highlight/CodeBlockHighlighter.hpp +66 -0
  136. package/cpp/highlight/CodeBlockLanguages.cpp +138 -0
  137. package/cpp/highlight/CodeBlockLanguages.hpp +25 -0
  138. package/cpp/highlight/HighlightGrammars.hpp +28 -0
  139. package/cpp/highlight/code_highlight_podspec.rb +211 -0
  140. package/cpp/highlight/gen-registry.mjs +155 -0
  141. package/cpp/highlight/grammar-versions.json +159 -0
  142. package/cpp/highlight/vendor/generated/generated_queries.h +1665 -0
  143. package/cpp/highlight/vendor/generated/generated_registry.cpp +59 -0
  144. package/cpp/parser/MD4CParser.cpp +173 -61
  145. package/cpp/parser/MD4CParser.hpp +1 -0
  146. package/cpp/parser/MarkdownASTNode.hpp +2 -1
  147. package/cpp/wasm/ASTSerializer.cpp +2 -0
  148. package/cpp/wasm/build.sh +1 -0
  149. package/cpp/wasm/md4c_wasm.cpp +3 -1
  150. package/docs/ACCESSIBILITY.md +14 -2
  151. package/docs/API_REFERENCE.md +231 -8
  152. package/docs/BREAKING_CHANGES.md +129 -0
  153. package/docs/CODE_HIGHLIGHT.md +133 -0
  154. package/docs/COPY_OPTIONS.md +21 -3
  155. package/docs/ELEMENTS_STRUCTURE.md +52 -4
  156. package/docs/IMAGE_CACHING.md +30 -0
  157. package/docs/INPUT.md +146 -5
  158. package/docs/LATEX_MATH.md +87 -45
  159. package/docs/MACOS.md +1 -1
  160. package/docs/MARKDOWN_STREAMING.md +27 -1
  161. package/docs/NATIVE_ASSETS.md +127 -0
  162. package/docs/RTL.md +1 -1
  163. package/docs/STYLES.md +46 -6
  164. package/docs/TESTING.md +112 -0
  165. package/docs/TEXT.md +16 -6
  166. package/docs/WEB.md +3 -1
  167. package/ios/EnrichedMarkdown.h +7 -0
  168. package/ios/EnrichedMarkdown.mm +262 -67
  169. package/ios/EnrichedMarkdownText.h +7 -0
  170. package/ios/EnrichedMarkdownText.mm +97 -68
  171. package/ios/attachments/ENRMImageAttachment.h +9 -0
  172. package/ios/attachments/ENRMImageAttachment.m +143 -40
  173. package/ios/attachments/ENRMMathInlineAttachment.h +2 -0
  174. package/ios/attachments/ENRMMathInlineAttachment.m +48 -81
  175. package/ios/attachments/ENRMMathInlineAttachmentShared.h +2 -0
  176. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
  177. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
  178. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +40 -0
  179. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +839 -23
  180. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +131 -0
  181. package/ios/input/ENRMAutoLinkDetector.h +2 -1
  182. package/ios/input/ENRMAutoLinkDetector.mm +79 -41
  183. package/ios/input/ENRMBlockEditCoordinator.h +71 -0
  184. package/ios/input/ENRMBlockEditCoordinator.mm +195 -0
  185. package/ios/input/ENRMBlockRange.h +28 -0
  186. package/ios/input/ENRMBlockRange.mm +30 -0
  187. package/ios/input/ENRMBlockStore.h +56 -0
  188. package/ios/input/ENRMBlockStore.mm +275 -0
  189. package/ios/input/ENRMBlockSyntaxSentinel.h +25 -0
  190. package/ios/input/ENRMBlockSyntaxSentinel.mm +80 -0
  191. package/ios/input/ENRMClipboardCoordinator.h +45 -0
  192. package/ios/input/ENRMClipboardCoordinator.mm +120 -0
  193. package/ios/input/ENRMDetectorPipeline.h +2 -1
  194. package/ios/input/ENRMEditPipeline.h +76 -0
  195. package/ios/input/ENRMEditPipeline.mm +228 -0
  196. package/ios/input/ENRMEditSession.h +36 -0
  197. package/ios/input/ENRMEditSession.mm +63 -0
  198. package/ios/input/ENRMFormattingStore.h +17 -0
  199. package/ios/input/ENRMFormattingStore.mm +95 -105
  200. package/ios/input/ENRMInputBlockType.h +91 -0
  201. package/ios/input/ENRMInputBlockType.mm +5 -0
  202. package/ios/input/ENRMInputDecorationDrawer.h +18 -0
  203. package/ios/input/ENRMInputEventEmitter.h +56 -0
  204. package/ios/input/ENRMInputEventEmitter.mm +308 -0
  205. package/ios/input/ENRMInputFormatter.h +29 -69
  206. package/ios/input/ENRMInputFormatter.mm +216 -124
  207. package/ios/input/ENRMInputFormatterStyle.h +99 -0
  208. package/ios/input/ENRMInputFormatterStyle.mm +188 -0
  209. package/ios/input/ENRMInputLayoutManager.h +9 -0
  210. package/ios/input/ENRMInputLayoutManager.mm +30 -0
  211. package/ios/input/ENRMInputListMarkerDrawer.h +32 -0
  212. package/ios/input/ENRMInputListMarkerDrawer.mm +426 -0
  213. package/ios/input/ENRMInputParser.h +10 -6
  214. package/ios/input/ENRMInputParser.mm +527 -171
  215. package/ios/input/ENRMInputRemend.mm +2 -2
  216. package/ios/input/ENRMInputStyleStateBuilder.h +40 -0
  217. package/ios/input/ENRMInputStyleStateBuilder.mm +60 -0
  218. package/ios/input/ENRMInputTextView.mm +103 -8
  219. package/ios/input/ENRMInputTypingAttributesController.h +42 -0
  220. package/ios/input/ENRMInputTypingAttributesController.mm +203 -0
  221. package/ios/input/ENRMLinkCoordinator.h +41 -0
  222. package/ios/input/ENRMLinkCoordinator.mm +89 -0
  223. package/ios/input/ENRMMarkdownSerializer.h +29 -5
  224. package/ios/input/ENRMMarkdownSerializer.mm +170 -48
  225. package/ios/input/ENRMMathAtom.h +26 -0
  226. package/ios/input/ENRMMathAtom.mm +12 -0
  227. package/ios/input/ENRMMentionCoordinator.h +45 -0
  228. package/ios/input/ENRMMentionCoordinator.mm +167 -0
  229. package/ios/input/ENRMRangeEditAdjustment.h +38 -0
  230. package/ios/input/ENRMRangeEditAdjustment.mm +91 -0
  231. package/ios/input/ENRMRangeStoreUtils.h +39 -0
  232. package/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm +6 -6
  233. package/ios/input/EnrichedMarkdownTextInput+Internal.h +11 -3
  234. package/ios/input/EnrichedMarkdownTextInput.h +7 -1
  235. package/ios/input/EnrichedMarkdownTextInput.mm +1104 -1024
  236. package/ios/input/InputStylePropsUtils.h +109 -68
  237. package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.mm +2 -1
  238. package/ios/input/styles/ENRMBlockHandler.h +46 -0
  239. package/ios/input/styles/ENRMHeadingBlockHandler.h +15 -0
  240. package/ios/input/styles/ENRMHeadingBlockHandler.mm +38 -0
  241. package/ios/input/styles/ENRMOrderedListBlockHandler.h +14 -0
  242. package/ios/input/styles/ENRMOrderedListBlockHandler.mm +48 -0
  243. package/ios/input/styles/ENRMUnorderedListBlockHandler.h +15 -0
  244. package/ios/input/styles/ENRMUnorderedListBlockHandler.mm +51 -0
  245. package/ios/internals/ENRMViewFreeMeasurement.h +331 -0
  246. package/ios/internals/EnrichedMarkdownShadowNode.h +1 -3
  247. package/ios/internals/EnrichedMarkdownShadowNode.mm +16 -20
  248. package/ios/internals/EnrichedMarkdownTextShadowNode.h +1 -3
  249. package/ios/internals/EnrichedMarkdownTextShadowNode.mm +15 -20
  250. package/ios/internals/MeasurementCache.h +33 -7
  251. package/ios/internals/ShadowMeasurementUtils.h +63 -58
  252. package/ios/math/ENRMMathChipController.h +74 -0
  253. package/ios/math/ENRMMathChipController.mm +476 -0
  254. package/ios/math/ENRMRaTeXBridge.swift +4 -1
  255. package/ios/parser/ENRMMarkdownParser.h +1 -8
  256. package/ios/parser/ENRMMarkdownParser.mm +2 -11
  257. package/ios/parser/MarkdownASTNode.h +2 -1
  258. package/ios/parser/MarkdownParserBridge.mm +4 -0
  259. package/ios/renderer/AttributedRenderer.m +20 -2
  260. package/ios/renderer/BaseRenderer.h +17 -2
  261. package/ios/renderer/BaseRenderer.m +30 -0
  262. package/ios/renderer/BlockquoteRenderer.h +1 -1
  263. package/ios/renderer/BlockquoteRenderer.m +144 -35
  264. package/ios/renderer/CodeBlockRenderer.h +1 -1
  265. package/ios/renderer/CodeBlockRenderer.m +27 -23
  266. package/ios/renderer/CodeRenderer.h +1 -1
  267. package/ios/renderer/CodeRenderer.m +3 -1
  268. package/ios/renderer/ENRMImageRenderer.h +1 -1
  269. package/ios/renderer/ENRMImageRenderer.m +5 -1
  270. package/ios/renderer/ENRMMathInlineRenderer.h +1 -1
  271. package/ios/renderer/ENRMMathInlineRenderer.m +5 -1
  272. package/ios/renderer/ENRMSpoilerRenderer.h +1 -1
  273. package/ios/renderer/ENRMSpoilerRenderer.m +3 -1
  274. package/ios/renderer/EmphasisRenderer.h +1 -1
  275. package/ios/renderer/EmphasisRenderer.m +3 -1
  276. package/ios/renderer/HeadingRenderer.h +1 -1
  277. package/ios/renderer/HeadingRenderer.m +13 -6
  278. package/ios/renderer/HighlightRenderer.h +1 -1
  279. package/ios/renderer/HighlightRenderer.m +3 -1
  280. package/ios/renderer/LinkRenderer.h +1 -1
  281. package/ios/renderer/LinkRenderer.m +3 -1
  282. package/ios/renderer/ListItemRenderer.h +13 -1
  283. package/ios/renderer/ListItemRenderer.m +102 -44
  284. package/ios/renderer/ListRenderer.h +2 -2
  285. package/ios/renderer/ListRenderer.m +63 -25
  286. package/ios/renderer/ParagraphRenderer.h +1 -1
  287. package/ios/renderer/ParagraphRenderer.m +16 -8
  288. package/ios/renderer/RenderContext.h +10 -0
  289. package/ios/renderer/RenderContext.m +44 -0
  290. package/ios/renderer/RendererFactory.m +14 -0
  291. package/ios/renderer/StrikethroughRenderer.h +1 -1
  292. package/ios/renderer/StrikethroughRenderer.m +3 -1
  293. package/ios/renderer/StrongRenderer.h +1 -1
  294. package/ios/renderer/StrongRenderer.m +3 -1
  295. package/ios/renderer/SubscriptRenderer.h +1 -1
  296. package/ios/renderer/SubscriptRenderer.m +3 -1
  297. package/ios/renderer/SuperscriptRenderer.h +1 -1
  298. package/ios/renderer/SuperscriptRenderer.m +3 -1
  299. package/ios/renderer/TextRenderer.h +2 -2
  300. package/ios/renderer/TextRenderer.m +3 -1
  301. package/ios/renderer/ThematicBreakRenderer.h +1 -1
  302. package/ios/renderer/ThematicBreakRenderer.m +3 -1
  303. package/ios/renderer/UnderlineRenderer.h +1 -1
  304. package/ios/renderer/UnderlineRenderer.m +3 -1
  305. package/ios/styles/StyleConfig.h +22 -0
  306. package/ios/styles/StyleConfig.mm +132 -0
  307. package/ios/utils/BlockquoteBorder.h +6 -0
  308. package/ios/utils/BlockquoteBorder.m +249 -52
  309. package/ios/utils/CodeBlockBackground.m +16 -2
  310. package/ios/utils/ENRMAtomicSize.h +65 -0
  311. package/ios/utils/ENRMCodeBlockContent.h +37 -0
  312. package/ios/utils/ENRMCodeBlockContent.mm +79 -0
  313. package/ios/utils/ENRMCodeBlockHighlighter.h +37 -0
  314. package/ios/utils/ENRMCodeBlockHighlighter.mm +51 -0
  315. package/ios/utils/ENRMFeatureFlags.h +7 -0
  316. package/ios/utils/ENRMImageDownloader.h +11 -1
  317. package/ios/utils/ENRMImageDownloader.m +60 -16
  318. package/ios/utils/ENRMLocalImageLoader.h +31 -0
  319. package/ios/utils/ENRMLocalImageLoader.m +68 -0
  320. package/ios/utils/ENRMMathFallback.h +26 -0
  321. package/ios/utils/ENRMMathFallback.m +18 -0
  322. package/ios/utils/ENRMTextViewSetup.h +35 -17
  323. package/ios/utils/EditMenuUtils.m +22 -1
  324. package/ios/utils/ImageRequestHeaderUtils.h +35 -0
  325. package/ios/utils/LastElementUtils.h +1 -0
  326. package/ios/utils/ListMarkerDrawer.m +29 -42
  327. package/ios/utils/MarkdownASTSerializer.m +4 -0
  328. package/ios/utils/ParagraphStyleUtils.h +5 -0
  329. package/ios/utils/ParagraphStyleUtils.m +77 -17
  330. package/ios/utils/RenderedMarkdownSegment.h +13 -1
  331. package/ios/utils/RenderedMarkdownSegment.m +20 -0
  332. package/ios/utils/SegmentRenderer.m +17 -4
  333. package/ios/utils/StreamingMarkdownFilter.h +11 -1
  334. package/ios/utils/StreamingMarkdownFilter.m +98 -2
  335. package/ios/utils/StylePropsUtils.h +63 -0
  336. package/ios/utils/TaskListTapUtils.m +24 -0
  337. package/ios/views/ENRMCodeBlockContainerView.h +46 -0
  338. package/ios/views/ENRMCodeBlockContainerView.m +566 -0
  339. package/ios/views/ENRMMathContainerView.h +12 -0
  340. package/ios/views/ENRMMathContainerView.m +71 -1
  341. package/ios/views/TableContainerView.h +18 -0
  342. package/ios/views/TableContainerView.m +259 -159
  343. package/jest.d.ts +1 -0
  344. package/jest.js +5 -0
  345. package/lib/module/EnrichedMarkdownNativeComponent.ts +65 -0
  346. package/lib/module/EnrichedMarkdownTextInput.js +86 -5
  347. package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
  348. package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +89 -5
  349. package/lib/module/EnrichedMarkdownTextNativeComponent.ts +66 -0
  350. package/lib/module/headingDefaults.js +34 -0
  351. package/lib/module/headingDefaults.js.map +1 -0
  352. package/lib/module/index.js.map +1 -1
  353. package/lib/module/jest/index.js +191 -0
  354. package/lib/module/jest/index.js.map +1 -0
  355. package/lib/module/native/EnrichedMarkdownText.js +30 -4
  356. package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
  357. package/lib/module/normalizeMarkdownStyle.js +81 -19
  358. package/lib/module/normalizeMarkdownStyle.js.map +1 -1
  359. package/lib/module/normalizeMarkdownStyle.web.js +56 -18
  360. package/lib/module/normalizeMarkdownStyle.web.js.map +1 -1
  361. package/lib/module/normalizeMarkdownTextInputStyle.js +62 -15
  362. package/lib/module/normalizeMarkdownTextInputStyle.js.map +1 -1
  363. package/lib/module/normalizeMenuItem.js +1 -1
  364. package/lib/module/utils/textInputState.js +26 -0
  365. package/lib/module/utils/textInputState.js.map +1 -0
  366. package/lib/module/web/EnrichedMarkdownText.js +9 -5
  367. package/lib/module/web/EnrichedMarkdownText.js.map +1 -1
  368. package/lib/module/web/parseMarkdown.js +4 -3
  369. package/lib/module/web/parseMarkdown.js.map +1 -1
  370. package/lib/module/web/renderers/InlineRenderers.js +6 -0
  371. package/lib/module/web/renderers/InlineRenderers.js.map +1 -1
  372. package/lib/module/web/renderers/ListRenderers.js +7 -2
  373. package/lib/module/web/renderers/ListRenderers.js.map +1 -1
  374. package/lib/module/web/renderers/index.js +7 -4
  375. package/lib/module/web/renderers/index.js.map +1 -1
  376. package/lib/module/web/styles.js +83 -6
  377. package/lib/module/web/styles.js.map +1 -1
  378. package/lib/module/web/utils.js +1 -0
  379. package/lib/module/web/utils.js.map +1 -1
  380. package/lib/module/web/wasm/md4c.js +0 -0
  381. package/lib/module/web/wasm/md4c.js.map +1 -1
  382. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +62 -0
  383. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
  384. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +95 -9
  385. package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
  386. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +80 -5
  387. package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
  388. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +62 -0
  389. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
  390. package/lib/typescript/src/headingDefaults.d.ts +9 -0
  391. package/lib/typescript/src/headingDefaults.d.ts.map +1 -0
  392. package/lib/typescript/src/index.d.ts +2 -2
  393. package/lib/typescript/src/index.d.ts.map +1 -1
  394. package/lib/typescript/src/index.web.d.ts +1 -1
  395. package/lib/typescript/src/index.web.d.ts.map +1 -1
  396. package/lib/typescript/src/jest/index.d.ts +6 -0
  397. package/lib/typescript/src/jest/index.d.ts.map +1 -0
  398. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +3 -3
  399. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +1 -1
  400. package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
  401. package/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +1 -1
  402. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts +19 -5
  403. package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts.map +1 -1
  404. package/lib/typescript/src/types/MarkdownStyle.d.ts +72 -0
  405. package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -1
  406. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +27 -0
  407. package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -1
  408. package/lib/typescript/src/types/MarkdownTextProps.d.ts +65 -1
  409. package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
  410. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts +19 -0
  411. package/lib/typescript/src/types/MarkdownTextProps.web.d.ts.map +1 -1
  412. package/lib/typescript/src/types/events.d.ts +19 -0
  413. package/lib/typescript/src/types/events.d.ts.map +1 -1
  414. package/lib/typescript/src/utils/textInputState.d.ts +24 -0
  415. package/lib/typescript/src/utils/textInputState.d.ts.map +1 -0
  416. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts +1 -1
  417. package/lib/typescript/src/web/EnrichedMarkdownText.d.ts.map +1 -1
  418. package/lib/typescript/src/web/parseMarkdown.d.ts +1 -1
  419. package/lib/typescript/src/web/parseMarkdown.d.ts.map +1 -1
  420. package/lib/typescript/src/web/renderers/InlineRenderers.d.ts.map +1 -1
  421. package/lib/typescript/src/web/renderers/ListRenderers.d.ts.map +1 -1
  422. package/lib/typescript/src/web/renderers/index.d.ts +2 -1
  423. package/lib/typescript/src/web/renderers/index.d.ts.map +1 -1
  424. package/lib/typescript/src/web/styles.d.ts +2 -1
  425. package/lib/typescript/src/web/styles.d.ts.map +1 -1
  426. package/lib/typescript/src/web/types.d.ts +6 -2
  427. package/lib/typescript/src/web/types.d.ts.map +1 -1
  428. package/lib/typescript/src/web/utils.d.ts.map +1 -1
  429. package/package.json +36 -9
  430. package/postinstall.mjs +131 -0
  431. package/ratex-version.json +21 -0
  432. package/src/EnrichedMarkdownNativeComponent.ts +65 -0
  433. package/src/EnrichedMarkdownTextInput.tsx +162 -8
  434. package/src/EnrichedMarkdownTextInputNativeComponent.ts +89 -5
  435. package/src/EnrichedMarkdownTextNativeComponent.ts +66 -0
  436. package/src/headingDefaults.ts +21 -0
  437. package/src/index.tsx +9 -0
  438. package/src/index.web.tsx +1 -0
  439. package/src/jest/index.tsx +215 -0
  440. package/src/native/EnrichedMarkdownText.tsx +40 -2
  441. package/src/normalizeMarkdownStyle.ts +102 -16
  442. package/src/normalizeMarkdownStyle.web.ts +63 -15
  443. package/src/normalizeMarkdownTextInputStyle.ts +110 -35
  444. package/src/normalizeMenuItem.ts +1 -1
  445. package/src/types/MarkdownStyle.ts +74 -0
  446. package/src/types/MarkdownStyleInternal.ts +39 -0
  447. package/src/types/MarkdownTextProps.ts +65 -0
  448. package/src/types/MarkdownTextProps.web.ts +19 -0
  449. package/src/types/events.ts +21 -0
  450. package/src/utils/textInputState.ts +35 -0
  451. package/src/web/EnrichedMarkdownText.tsx +16 -2
  452. package/src/web/parseMarkdown.ts +6 -2
  453. package/src/web/renderers/InlineRenderers.tsx +5 -0
  454. package/src/web/renderers/ListRenderers.tsx +14 -2
  455. package/src/web/renderers/index.tsx +6 -2
  456. package/src/web/styles.ts +89 -5
  457. package/src/web/types.ts +6 -1
  458. package/src/web/utils.ts +1 -0
  459. package/src/web/wasm/md4c.js +0 -0
  460. package/vendor-grammars.mjs +511 -0
  461. package/vendor-ratex.mjs +173 -0
  462. package/app.plugin.js +0 -2
  463. package/plugin/build/withAndroidMath.js +0 -19
  464. package/plugin/build/withIosMath.js +0 -28
  465. package/plugin/build/withReactNativeEnrichedMarkdown.js +0 -11
  466. package/plugin/src/withAndroidMath.ts +0 -24
  467. package/plugin/src/withIosMath.ts +0 -35
  468. package/plugin/src/withReactNativeEnrichedMarkdown.ts +0 -17
  469. package/plugin/tsconfig.build.json +0 -16
@@ -7,8 +7,8 @@ typedef struct {
7
7
  } ENRMDelimiterPair;
8
8
 
9
9
  static const ENRMDelimiterPair kDelimiterPairs[] = {
10
- {@"**", @"**", YES}, {@"*", @"*", YES}, {@"_", @"_", YES}, {@"~~", @"~~", YES},
11
- {@"||", @"||", YES}, {@"`", @"`", YES}, {@"[", @"]", NO},
10
+ {@"***", @"***", YES}, {@"**", @"**", YES}, {@"*", @"*", YES}, {@"_", @"_", YES},
11
+ {@"~~", @"~~", YES}, {@"||", @"||", YES}, {@"`", @"`", YES}, {@"[", @"]", NO},
12
12
  };
13
13
  static const NSUInteger kDelimiterPairCount = sizeof(kDelimiterPairs) / sizeof(kDelimiterPairs[0]);
14
14
 
@@ -0,0 +1,40 @@
1
+ #pragma once
2
+
3
+ #import "ENRMBlockRange.h"
4
+ #import "ENRMInputStyledRange.h"
5
+ #import <Foundation/Foundation.h>
6
+
7
+ NS_ASSUME_NONNULL_BEGIN
8
+
9
+ typedef struct {
10
+ BOOL bold;
11
+ BOOL italic;
12
+ BOOL underline;
13
+ BOOL strikethrough;
14
+ BOOL spoiler;
15
+ BOOL link;
16
+ NSInteger headingLevel;
17
+ BOOL unorderedList;
18
+ BOOL orderedList;
19
+ NSInteger listDepth;
20
+ } ENRMInputStyleSnapshot;
21
+
22
+ @protocol ENRMInputStyleStateDataSource <NSObject>
23
+
24
+ - (NSRange)selectedRange;
25
+ - (BOOL)isEffectiveStyleActive:(ENRMInputStyleType)type atPosition:(NSUInteger)position;
26
+ - (BOOL)isStyleActive:(ENRMInputStyleType)type inRange:(NSRange)range;
27
+ - (NSInteger)headingLevelForCursorParagraph;
28
+ - (nullable ENRMBlockRange *)listBlockForCursorParagraph;
29
+
30
+ @end
31
+
32
+ @interface ENRMInputStyleStateBuilder : NSObject
33
+
34
+ + (ENRMInputStyleSnapshot)snapshotAtCurrentCursor:(id<ENRMInputStyleStateDataSource>)dataSource;
35
+
36
+ + (ENRMInputStyleSnapshot)snapshotForRange:(NSRange)range dataSource:(id<ENRMInputStyleStateDataSource>)dataSource;
37
+
38
+ @end
39
+
40
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,60 @@
1
+ #import "ENRMInputStyleStateBuilder.h"
2
+
3
+ @implementation ENRMInputStyleStateBuilder
4
+
5
+ + (ENRMInputStyleSnapshot)snapshotAtCurrentCursor:(id<ENRMInputStyleStateDataSource>)dataSource
6
+ {
7
+ NSUInteger cursor = [dataSource selectedRange].location;
8
+ ENRMInputStyleSnapshot snapshot = {};
9
+ if (cursor == NSNotFound) {
10
+ return snapshot;
11
+ }
12
+ snapshot.bold = [dataSource isEffectiveStyleActive:ENRMInputStyleTypeStrong atPosition:cursor];
13
+ snapshot.italic = [dataSource isEffectiveStyleActive:ENRMInputStyleTypeEmphasis atPosition:cursor];
14
+ snapshot.underline = [dataSource isEffectiveStyleActive:ENRMInputStyleTypeUnderline atPosition:cursor];
15
+ snapshot.strikethrough = [dataSource isEffectiveStyleActive:ENRMInputStyleTypeStrikethrough atPosition:cursor];
16
+ snapshot.spoiler = [dataSource isEffectiveStyleActive:ENRMInputStyleTypeSpoiler atPosition:cursor];
17
+ snapshot.link = [dataSource isEffectiveStyleActive:ENRMInputStyleTypeLink atPosition:cursor];
18
+ snapshot.headingLevel = [dataSource headingLevelForCursorParagraph];
19
+
20
+ ENRMBlockRange *listBlock = [dataSource listBlockForCursorParagraph];
21
+ snapshot.unorderedList = listBlock != nil && listBlock.type == ENRMInputBlockTypeUnorderedListItem;
22
+ snapshot.orderedList = listBlock != nil && listBlock.type == ENRMInputBlockTypeOrderedListItem;
23
+ snapshot.listDepth = listBlock != nil ? listBlock.level : 0;
24
+
25
+ return snapshot;
26
+ }
27
+
28
+ + (ENRMInputStyleSnapshot)snapshotForRange:(NSRange)range dataSource:(id<ENRMInputStyleStateDataSource>)dataSource
29
+ {
30
+ ENRMInputStyleSnapshot snapshot = {};
31
+ if (range.location == NSNotFound) {
32
+ return snapshot;
33
+ }
34
+ if (range.length > 0) {
35
+ snapshot.bold = [dataSource isStyleActive:ENRMInputStyleTypeStrong inRange:range];
36
+ snapshot.italic = [dataSource isStyleActive:ENRMInputStyleTypeEmphasis inRange:range];
37
+ snapshot.underline = [dataSource isStyleActive:ENRMInputStyleTypeUnderline inRange:range];
38
+ snapshot.strikethrough = [dataSource isStyleActive:ENRMInputStyleTypeStrikethrough inRange:range];
39
+ snapshot.spoiler = [dataSource isStyleActive:ENRMInputStyleTypeSpoiler inRange:range];
40
+ snapshot.link = [dataSource isStyleActive:ENRMInputStyleTypeLink inRange:range];
41
+ } else {
42
+ snapshot.bold = [dataSource isEffectiveStyleActive:ENRMInputStyleTypeStrong atPosition:range.location];
43
+ snapshot.italic = [dataSource isEffectiveStyleActive:ENRMInputStyleTypeEmphasis atPosition:range.location];
44
+ snapshot.underline = [dataSource isEffectiveStyleActive:ENRMInputStyleTypeUnderline atPosition:range.location];
45
+ snapshot.strikethrough = [dataSource isEffectiveStyleActive:ENRMInputStyleTypeStrikethrough
46
+ atPosition:range.location];
47
+ snapshot.spoiler = [dataSource isEffectiveStyleActive:ENRMInputStyleTypeSpoiler atPosition:range.location];
48
+ snapshot.link = [dataSource isEffectiveStyleActive:ENRMInputStyleTypeLink atPosition:range.location];
49
+ }
50
+ snapshot.headingLevel = [dataSource headingLevelForCursorParagraph];
51
+
52
+ ENRMBlockRange *listBlock = [dataSource listBlockForCursorParagraph];
53
+ snapshot.unorderedList = listBlock != nil && listBlock.type == ENRMInputBlockTypeUnorderedListItem;
54
+ snapshot.orderedList = listBlock != nil && listBlock.type == ENRMInputBlockTypeOrderedListItem;
55
+ snapshot.listDepth = listBlock != nil ? listBlock.level : 0;
56
+
57
+ return snapshot;
58
+ }
59
+
60
+ @end
@@ -1,15 +1,19 @@
1
1
  #import "ENRMInputTextView.h"
2
+ #import "ENRMInputLayoutManager.h"
3
+ #import "EnrichedMarkdownTextInput+Internal.h"
2
4
  #import "EnrichedMarkdownTextInput.h"
3
5
  #import "PasteboardUtils.h"
4
6
  #if TARGET_OS_OSX
5
- #import "EnrichedMarkdownTextInput+Internal.h"
7
+ #import <objc/message.h>
6
8
  #endif
7
9
 
8
10
  NSString *const kENRMMarkdownPasteboardType = @"com.swmansion.enriched-markdown.markdown";
9
11
 
10
12
  #if !TARGET_OS_OSX
11
13
 
12
- @implementation ENRMInputTextView
14
+ @implementation ENRMInputTextView {
15
+ CGFloat _lastLayoutWidth;
16
+ }
13
17
 
14
18
  - (void)copy:(id)sender
15
19
  {
@@ -46,13 +50,27 @@ NSString *const kENRMMarkdownPasteboardType = @"com.swmansion.enriched-markdown.
46
50
  markdown = [[NSString alloc] initWithData:markdownValue encoding:NSUTF8StringEncoding];
47
51
  }
48
52
 
53
+ NSString *plainText = pasteboard.string;
54
+
55
+ // Both flavors are read before anything is decided, then nothing is written:
56
+ // JS owns the paste from here and must call resolvePaste. Mutating the buffer
57
+ // first would mean a handler that dies mid-flight leaves the selection gone
58
+ // with no text to show for it — a no-op paste is the visible failure.
59
+ if (self.markdownTextInput.interceptPaste && (plainText.length > 0 || markdown.length > 0)) {
60
+ [self.markdownTextInput emitOnPasteWithText:(plainText ?: @"") markdown:(markdown ?: @"")];
61
+ return;
62
+ }
63
+
49
64
  if (markdown.length > 0 && self.markdownTextInput != nil) {
50
65
  [self.markdownTextInput pasteMarkdown:markdown];
51
66
  return;
52
67
  }
53
68
 
54
- NSString *plainText = pasteboard.string;
55
- if (plainText.length > 0) {
69
+ // External plain text is treated as markdown so pasted syntax ("- ", "#",
70
+ // "**") formats instead of landing literal; syntax-free text is unchanged.
71
+ if (plainText.length > 0 && self.markdownTextInput != nil) {
72
+ [self.markdownTextInput pasteMarkdown:plainText];
73
+ } else if (plainText.length > 0) {
56
74
  [self replaceRange:self.selectedTextRange withText:plainText];
57
75
  }
58
76
  }
@@ -71,16 +89,65 @@ NSString *const kENRMMarkdownPasteboardType = @"com.swmansion.enriched-markdown.
71
89
  - (void)layoutSubviews
72
90
  {
73
91
  [super layoutSubviews];
74
- if (self.markdownTextInput != nil) {
92
+ CGFloat currentWidth = self.bounds.size.width;
93
+ if (self.markdownTextInput != nil && fabs(currentWidth - _lastLayoutWidth) > 0.5) {
94
+ _lastLayoutWidth = currentWidth;
75
95
  [self.markdownTextInput scheduleRelayoutIfNeeded];
76
96
  }
77
97
  }
78
98
 
99
+ - (void)deleteBackward
100
+ {
101
+ // Backspace at the very start of the document doesn't fire the text-change
102
+ // delegate (nothing precedes the caret), so removing/outdenting the first
103
+ // line's list marker has to be handled here.
104
+ if (self.markdownTextInput != nil && [self.markdownTextInput handleBackspaceAtDocumentStart]) {
105
+ return;
106
+ }
107
+ [super deleteBackward];
108
+ }
109
+
110
+ /// Hardware-keyboard Tab / Shift+Tab indent and outdent the current list item.
111
+ /// UIKeyCommand only fires for an attached keyboard; on-screen Tab/Backspace go
112
+ /// through the text-change delegate (see handleListKeyForReplacementRange:).
113
+ - (NSArray<UIKeyCommand *> *)keyCommands
114
+ {
115
+ return @[
116
+ [UIKeyCommand keyCommandWithInput:@"\t" modifierFlags:0 action:@selector(enrmIndentList:)],
117
+ [UIKeyCommand keyCommandWithInput:@"\t" modifierFlags:UIKeyModifierShift action:@selector(enrmOutdentList:)],
118
+ ];
119
+ }
120
+
121
+ - (void)enrmIndentList:(UIKeyCommand *)command
122
+ {
123
+ [self.markdownTextInput indentList];
124
+ }
125
+
126
+ - (void)enrmOutdentList:(UIKeyCommand *)command
127
+ {
128
+ [self.markdownTextInput outdentList];
129
+ }
130
+
131
+ - (void)drawRect:(CGRect)rect
132
+ {
133
+ [super drawRect:rect];
134
+ // A wholly empty editor has no glyphs, so the layout manager's
135
+ // drawGlyphsForGlyphRange: never runs — draw decorations here instead.
136
+ if (self.text.length == 0) {
137
+ NSLayoutManager *layoutManager = self.layoutManager;
138
+ if ([layoutManager isKindOfClass:[ENRMInputLayoutManager class]]) {
139
+ [(ENRMInputLayoutManager *)layoutManager drawEmptyEditorDecorationsWithInset:self.textContainerInset];
140
+ }
141
+ }
142
+ }
143
+
79
144
  @end
80
145
 
81
146
  #else // TARGET_OS_OSX
82
147
 
83
- @implementation ENRMInputTextView
148
+ @implementation ENRMInputTextView {
149
+ CGFloat _lastLayoutWidth;
150
+ }
84
151
 
85
152
  - (void)copy:(id)sender
86
153
  {
@@ -115,8 +182,12 @@ NSString *const kENRMMarkdownPasteboardType = @"com.swmansion.enriched-markdown.
115
182
  return;
116
183
  }
117
184
 
185
+ // External plain text is treated as markdown so pasted syntax ("- ", "#",
186
+ // "**") formats instead of landing literal; syntax-free text is unchanged.
118
187
  NSString *plainText = [pasteboard stringForType:NSPasteboardTypeString];
119
- if (plainText.length > 0) {
188
+ if (plainText.length > 0 && self.markdownTextInput != nil) {
189
+ [self.markdownTextInput pasteMarkdown:plainText];
190
+ } else if (plainText.length > 0) {
120
191
  [self insertText:plainText replacementRange:self.selectedRange];
121
192
  }
122
193
  }
@@ -153,14 +224,38 @@ NSString *const kENRMMarkdownPasteboardType = @"com.swmansion.enriched-markdown.
153
224
  return menu;
154
225
  }
155
226
 
227
+ - (void)setTypingAttributes:(NSDictionary *)typingAttributes
228
+ {
229
+ // RCTUITextView's override discards the value and always resets to
230
+ // defaultTextAttributes. We need the actual value (e.g. list paragraph
231
+ // indent) to reach NSTextView so the caret positions correctly.
232
+ struct objc_super superSuper = {self, [NSTextView class]};
233
+ ((void (*)(struct objc_super *, SEL, NSDictionary *))objc_msgSendSuper)(&superSuper, _cmd, typingAttributes);
234
+ }
235
+
156
236
  - (void)layout
157
237
  {
158
238
  [super layout];
159
- if (self.markdownTextInput != nil) {
239
+ CGFloat currentWidth = self.bounds.size.width;
240
+ if (self.markdownTextInput != nil && fabs(currentWidth - _lastLayoutWidth) > 0.5) {
241
+ _lastLayoutWidth = currentWidth;
160
242
  [self.markdownTextInput scheduleRelayoutIfNeeded];
161
243
  }
162
244
  }
163
245
 
246
+ - (void)drawRect:(NSRect)rect
247
+ {
248
+ [super drawRect:rect];
249
+ if (self.string.length == 0) {
250
+ NSLayoutManager *lm = self.layoutManager;
251
+ if ([lm isKindOfClass:[ENRMInputLayoutManager class]]) {
252
+ NSEdgeInsets insets = self.textContainerInsets;
253
+ insets.left += self.textContainer.lineFragmentPadding;
254
+ [(ENRMInputLayoutManager *)lm drawEmptyEditorDecorationsWithInset:insets];
255
+ }
256
+ }
257
+ }
258
+
164
259
  @end
165
260
 
166
261
  #endif
@@ -0,0 +1,42 @@
1
+ #pragma once
2
+
3
+ #import "ENRMBlockRange.h"
4
+ #import "ENRMEditSession.h"
5
+ #import "ENRMInputFormatterStyle.h"
6
+ #import "ENRMInputStyledRange.h"
7
+ #import "ENRMInputTextView.h"
8
+ #import <Foundation/Foundation.h>
9
+
10
+ NS_ASSUME_NONNULL_BEGIN
11
+
12
+ @protocol ENRMInputTypingAttributesDataSource <NSObject>
13
+
14
+ - (NSRange)selectedRange;
15
+ - (NSInteger)headingLevelForCursorParagraph;
16
+ - (nullable ENRMBlockRange *)listBlockForCursorParagraph;
17
+ - (BOOL)isStyleAdjacentBefore:(ENRMInputStyleType)type position:(NSUInteger)position;
18
+ - (BOOL)isStyleActive:(ENRMInputStyleType)type atPosition:(NSUInteger)position;
19
+
20
+ @end
21
+
22
+ @interface ENRMInputTypingAttributesController : NSObject
23
+
24
+ - (instancetype)initWithTextView:(ENRMPlatformTextView *)textView
25
+ formatterStyle:(ENRMInputFormatterStyle *)style
26
+ dataSource:(id<ENRMInputTypingAttributesDataSource>)dataSource
27
+ editSession:(ENRMEditSession *)editSession;
28
+
29
+ - (BOOL)isEffectiveStyleActive:(ENRMInputStyleType)type atPosition:(NSUInteger)position;
30
+ - (void)togglePendingStyle:(ENRMInputStyleType)type wasActive:(BOOL)wasActive hasSelection:(BOOL)hasSelection;
31
+ - (void)clearPendingStyle:(ENRMInputStyleType)type;
32
+ - (void)syncWithCursorBlock;
33
+ - (void)syncWithPendingStyles;
34
+ - (void)resetForSelectionChange;
35
+ - (void)clearListParagraphStyle;
36
+
37
+ @property (nonatomic, readonly) NSSet<NSNumber *> *pendingStyles;
38
+ @property (nonatomic, readonly) NSSet<NSNumber *> *pendingStyleRemovals;
39
+
40
+ @end
41
+
42
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,203 @@
1
+ #import "ENRMInputTypingAttributesController.h"
2
+ #import "ENRMInputBlockType.h"
3
+
4
+ @implementation ENRMInputTypingAttributesController {
5
+ __weak ENRMPlatformTextView *_textView;
6
+ __weak id<ENRMInputTypingAttributesDataSource> _dataSource;
7
+ ENRMInputFormatterStyle *_formatterStyle;
8
+ ENRMEditSession *_editSession;
9
+
10
+ NSMutableSet<NSNumber *> *_pendingStyles;
11
+ NSMutableSet<NSNumber *> *_pendingStyleRemovals;
12
+ }
13
+
14
+ - (instancetype)initWithTextView:(ENRMPlatformTextView *)textView
15
+ formatterStyle:(ENRMInputFormatterStyle *)style
16
+ dataSource:(id<ENRMInputTypingAttributesDataSource>)dataSource
17
+ editSession:(ENRMEditSession *)editSession
18
+ {
19
+ self = [super init];
20
+ if (self) {
21
+ _textView = textView;
22
+ _formatterStyle = style;
23
+ _dataSource = dataSource;
24
+ _editSession = editSession;
25
+ _pendingStyles = [NSMutableSet set];
26
+ _pendingStyleRemovals = [NSMutableSet set];
27
+ }
28
+ return self;
29
+ }
30
+
31
+ #pragma mark - Properties
32
+
33
+ - (NSSet<NSNumber *> *)pendingStyles
34
+ {
35
+ return [_pendingStyles copy];
36
+ }
37
+
38
+ - (NSSet<NSNumber *> *)pendingStyleRemovals
39
+ {
40
+ return [_pendingStyleRemovals copy];
41
+ }
42
+
43
+ #pragma mark - Style queries
44
+
45
+ - (BOOL)isEffectiveStyleActive:(ENRMInputStyleType)type atPosition:(NSUInteger)position
46
+ {
47
+ BOOL inRange = [_dataSource isStyleActive:type atPosition:position];
48
+ NSNumber *key = @(type);
49
+ if ([_pendingStyleRemovals containsObject:key]) {
50
+ return NO;
51
+ }
52
+ if ([_pendingStyles containsObject:key]) {
53
+ return YES;
54
+ }
55
+ return inRange;
56
+ }
57
+
58
+ #pragma mark - Pending style mutations
59
+
60
+ - (void)togglePendingStyle:(ENRMInputStyleType)type wasActive:(BOOL)wasActive hasSelection:(BOOL)hasSelection
61
+ {
62
+ NSNumber *key = @(type);
63
+ if (hasSelection) {
64
+ [_pendingStyles removeObject:key];
65
+ [_pendingStyleRemovals removeObject:key];
66
+ } else {
67
+ if ([_pendingStyleRemovals containsObject:key]) {
68
+ [_pendingStyleRemovals removeObject:key];
69
+ } else if ([_pendingStyles containsObject:key]) {
70
+ [_pendingStyles removeObject:key];
71
+ } else if (wasActive) {
72
+ [_pendingStyleRemovals addObject:key];
73
+ } else {
74
+ [_pendingStyles addObject:key];
75
+ }
76
+ }
77
+ }
78
+
79
+ - (void)clearPendingStyle:(ENRMInputStyleType)type
80
+ {
81
+ NSNumber *key = @(type);
82
+ [_pendingStyles removeObject:key];
83
+ [_pendingStyleRemovals removeObject:key];
84
+ }
85
+
86
+ #pragma mark - Typing attribute synchronization
87
+
88
+ - (void)syncWithCursorBlock
89
+ {
90
+ UIFontDescriptorSymbolicTraits traits = 0;
91
+ if ([_pendingStyles containsObject:@(ENRMInputStyleTypeStrong)]) {
92
+ traits |= UIFontDescriptorTraitBold;
93
+ }
94
+ if ([_pendingStyles containsObject:@(ENRMInputStyleTypeEmphasis)]) {
95
+ traits |= UIFontDescriptorTraitItalic;
96
+ }
97
+
98
+ NSInteger headingLevel = [_dataSource headingLevelForCursorParagraph];
99
+
100
+ UIFont *font;
101
+ if (headingLevel >= 1 && headingLevel <= 6) {
102
+ UIFont *headingFont = [_formatterStyle headingFontForLevel:headingLevel];
103
+ UIFontDescriptorSymbolicTraits merged = headingFont.fontDescriptor.symbolicTraits | traits;
104
+ UIFontDescriptor *descriptor = [headingFont.fontDescriptor fontDescriptorWithSymbolicTraits:merged];
105
+ font = descriptor ? [UIFont fontWithDescriptor:descriptor size:0] : headingFont;
106
+ } else {
107
+ font = [_formatterStyle fontForTraits:traits];
108
+ }
109
+
110
+ NSMutableDictionary *attrs = [_textView.typingAttributes mutableCopy];
111
+ attrs[NSFontAttributeName] = font;
112
+ RCTUIColor *headingColor = headingLevel >= 1 ? [_formatterStyle headingColorForLevel:headingLevel] : nil;
113
+ attrs[NSForegroundColorAttributeName] = headingColor ?: _formatterStyle.baseTextColor;
114
+
115
+ ENRMBlockRange *typingListBlock = [_dataSource listBlockForCursorParagraph];
116
+ if (typingListBlock != nil) {
117
+ NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
118
+ CGFloat indent = (typingListBlock.level + 1) * kENRMListIndentPerDepth;
119
+ paragraph.firstLineHeadIndent = indent;
120
+ paragraph.headIndent = indent;
121
+ paragraph.paragraphSpacingBefore = _formatterStyle.listItemSpacing;
122
+ attrs[NSParagraphStyleAttributeName] = paragraph;
123
+ } else {
124
+ [attrs removeObjectForKey:NSParagraphStyleAttributeName];
125
+ }
126
+
127
+ if (![attrs isEqualToDictionary:_textView.typingAttributes]) {
128
+ _textView.typingAttributes = attrs;
129
+ }
130
+ }
131
+
132
+ - (void)syncWithPendingStyles
133
+ {
134
+ UIFontDescriptorSymbolicTraits traits = 0;
135
+ if ([_pendingStyles containsObject:@(ENRMInputStyleTypeStrong)]) {
136
+ traits |= UIFontDescriptorTraitBold;
137
+ }
138
+ if ([_pendingStyles containsObject:@(ENRMInputStyleTypeEmphasis)]) {
139
+ traits |= UIFontDescriptorTraitItalic;
140
+ }
141
+
142
+ NSMutableDictionary *attrs = [_textView.typingAttributes mutableCopy];
143
+ attrs[NSFontAttributeName] = [_formatterStyle fontForTraits:traits];
144
+ _textView.typingAttributes = attrs;
145
+ }
146
+
147
+ - (void)resetForSelectionChange
148
+ {
149
+ if (_editSession.isPostEditGracePeriod) {
150
+ return;
151
+ }
152
+ [_pendingStyles removeAllObjects];
153
+ [_pendingStyleRemovals removeAllObjects];
154
+ [self rebuildFromContext];
155
+ if ([_dataSource selectedRange].length == 0) {
156
+ [self syncWithCursorBlock];
157
+ }
158
+ }
159
+
160
+ - (void)clearListParagraphStyle
161
+ {
162
+ if (_textView.typingAttributes[NSParagraphStyleAttributeName] == nil) {
163
+ return;
164
+ }
165
+ NSMutableDictionary *attrs = [_textView.typingAttributes mutableCopy];
166
+ [attrs removeObjectForKey:NSParagraphStyleAttributeName];
167
+ _textView.typingAttributes = attrs;
168
+ }
169
+
170
+ #pragma mark - Private
171
+
172
+ - (void)rebuildFromContext
173
+ {
174
+ static const ENRMInputStyleType inlineStyles[] = {
175
+ ENRMInputStyleTypeStrong, ENRMInputStyleTypeEmphasis, ENRMInputStyleTypeUnderline,
176
+ ENRMInputStyleTypeStrikethrough, ENRMInputStyleTypeSpoiler,
177
+ };
178
+
179
+ NSRange selection = [_dataSource selectedRange];
180
+
181
+ if (selection.length > 0) {
182
+ for (NSUInteger i = 0; i < sizeof(inlineStyles) / sizeof(inlineStyles[0]); i++) {
183
+ ENRMInputStyleType type = inlineStyles[i];
184
+ if ([_dataSource isStyleActive:type atPosition:selection.location]) {
185
+ [_pendingStyles addObject:@(type)];
186
+ }
187
+ }
188
+ return;
189
+ }
190
+
191
+ if (selection.location == 0) {
192
+ return;
193
+ }
194
+
195
+ for (NSUInteger i = 0; i < sizeof(inlineStyles) / sizeof(inlineStyles[0]); i++) {
196
+ ENRMInputStyleType type = inlineStyles[i];
197
+ if ([_dataSource isStyleAdjacentBefore:type position:selection.location]) {
198
+ [_pendingStyles addObject:@(type)];
199
+ }
200
+ }
201
+ }
202
+
203
+ @end
@@ -0,0 +1,41 @@
1
+ #pragma once
2
+
3
+ #import "ENRMFormattingRange.h"
4
+ #import "ENRMFormattingStore.h"
5
+ #import <Foundation/Foundation.h>
6
+
7
+ @class AutoLinkDetector;
8
+
9
+ NS_ASSUME_NONNULL_BEGIN
10
+
11
+ @protocol ENRMAutoLinkDetecting <NSObject>
12
+ - (void)clearAutoLinkInRange:(NSRange)range;
13
+ @end
14
+
15
+ @interface ENRMLinkCoordinator : NSObject
16
+
17
+ - (instancetype)initWithFormattingStore:(ENRMFormattingStore *)formattingStore
18
+ autoLinkDetector:(id<ENRMAutoLinkDetecting>)autoLinkDetector;
19
+
20
+ - (NSString *)sanitizeURL:(NSString *)url;
21
+ - (nullable ENRMFormattingRange *)linkAtPosition:(NSUInteger)position;
22
+
23
+ /// Sets a link on the selection range, or updates an existing link's URL at the cursor.
24
+ /// Returns YES if a mutation occurred.
25
+ - (BOOL)setLinkURL:(NSString *)url atCursor:(NSUInteger)cursor selection:(NSRange)selection;
26
+
27
+ /// Adds a new link range (sanitizes the URL, clears auto-links).
28
+ - (void)addLinkWithURL:(NSString *)url start:(NSUInteger)start end:(NSUInteger)end;
29
+
30
+ /// Adds a link range with an already-sanitized URL (no auto-link clearing).
31
+ - (void)addLinkDirectWithURL:(NSString *)url start:(NSUInteger)start end:(NSUInteger)end;
32
+
33
+ /// Removes the link at the given position. Returns YES if a link was found and removed.
34
+ - (BOOL)removeLinkAtPosition:(NSUInteger)position;
35
+
36
+ /// Returns the link range containing `position - 1`, for atomic link deletion.
37
+ - (nullable ENRMFormattingRange *)linkRangeForDeletionAtPosition:(NSUInteger)position;
38
+
39
+ @end
40
+
41
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,89 @@
1
+ #import "ENRMLinkCoordinator.h"
2
+
3
+ @implementation ENRMLinkCoordinator {
4
+ ENRMFormattingStore *_formattingStore;
5
+ id<ENRMAutoLinkDetecting> _autoLinkDetector;
6
+ }
7
+
8
+ - (instancetype)initWithFormattingStore:(ENRMFormattingStore *)formattingStore
9
+ autoLinkDetector:(id<ENRMAutoLinkDetecting>)autoLinkDetector
10
+ {
11
+ if (self = [super init]) {
12
+ _formattingStore = formattingStore;
13
+ _autoLinkDetector = autoLinkDetector;
14
+ }
15
+ return self;
16
+ }
17
+
18
+ - (NSString *)sanitizeURL:(NSString *)url
19
+ {
20
+ NSString *result = [url stringByReplacingOccurrencesOfString:@"(" withString:@"%28"];
21
+ return [result stringByReplacingOccurrencesOfString:@")" withString:@"%29"];
22
+ }
23
+
24
+ - (nullable ENRMFormattingRange *)linkAtPosition:(NSUInteger)position
25
+ {
26
+ return [_formattingStore rangeOfType:ENRMInputStyleTypeLink containingPosition:position];
27
+ }
28
+
29
+ - (BOOL)setLinkURL:(NSString *)url atCursor:(NSUInteger)cursor selection:(NSRange)selection
30
+ {
31
+ ENRMFormattingRange *activeLink = [_formattingStore rangeOfType:ENRMInputStyleTypeLink containingPosition:cursor];
32
+
33
+ if (activeLink != nil) {
34
+ activeLink.url = url;
35
+ [_autoLinkDetector clearAutoLinkInRange:activeLink.range];
36
+ return YES;
37
+ }
38
+
39
+ if (selection.length > 0) {
40
+ ENRMFormattingRange *linkRange = [ENRMFormattingRange rangeWithType:ENRMInputStyleTypeLink range:selection url:url];
41
+ [_formattingStore addRange:linkRange];
42
+ [_autoLinkDetector clearAutoLinkInRange:selection];
43
+ return YES;
44
+ }
45
+
46
+ return NO;
47
+ }
48
+
49
+ - (void)addLinkWithURL:(NSString *)url start:(NSUInteger)start end:(NSUInteger)end
50
+ {
51
+ if (start >= end) {
52
+ return;
53
+ }
54
+ NSRange range = NSMakeRange(start, end - start);
55
+ [_autoLinkDetector clearAutoLinkInRange:range];
56
+ [_formattingStore addRange:[ENRMFormattingRange rangeWithType:ENRMInputStyleTypeLink
57
+ range:range
58
+ url:[self sanitizeURL:url]]];
59
+ }
60
+
61
+ - (void)addLinkDirectWithURL:(NSString *)url start:(NSUInteger)start end:(NSUInteger)end
62
+ {
63
+ if (start >= end) {
64
+ return;
65
+ }
66
+ [_formattingStore addRange:[ENRMFormattingRange rangeWithType:ENRMInputStyleTypeLink
67
+ range:NSMakeRange(start, end - start)
68
+ url:url]];
69
+ }
70
+
71
+ - (BOOL)removeLinkAtPosition:(NSUInteger)position
72
+ {
73
+ ENRMFormattingRange *activeLink = [_formattingStore rangeOfType:ENRMInputStyleTypeLink containingPosition:position];
74
+ if (activeLink == nil) {
75
+ return NO;
76
+ }
77
+ [_formattingStore removeRange:activeLink];
78
+ return YES;
79
+ }
80
+
81
+ - (nullable ENRMFormattingRange *)linkRangeForDeletionAtPosition:(NSUInteger)position
82
+ {
83
+ if (position == 0) {
84
+ return nil;
85
+ }
86
+ return [_formattingStore rangeOfType:ENRMInputStyleTypeLink containingPosition:position - 1];
87
+ }
88
+
89
+ @end