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
@@ -5,6 +5,7 @@
5
5
  #include <TargetConditionals.h>
6
6
 
7
7
  #if ENRICHED_MARKDOWN_MATH
8
+ #import "ENRMMathFallback.h"
8
9
  #import "PasteboardUtils.h"
9
10
  #if __has_include("ReactNativeEnrichedMarkdown-Swift.h")
10
11
  #import "ReactNativeEnrichedMarkdown-Swift.h"
@@ -20,14 +21,21 @@
20
21
 
21
22
  @interface ENRMRaTeXCanvasView : RCTUIView
22
23
  @property (nonatomic, strong, nullable) ENRMRaTeXRenderResult *renderResult;
24
+ // Visible-source fallback when RaTeX cannot parse the block, drawn wrapped;
25
+ // see ENRMMathFallback.h.
26
+ @property (nonatomic, strong, nullable) NSAttributedString *fallbackSource;
23
27
  @end
24
28
 
25
29
  @implementation ENRMRaTeXCanvasView
26
30
 
27
31
  - (void)drawRect:(CGRect)rect
28
32
  {
29
- if (!_renderResult)
33
+ if (!_renderResult) {
34
+ if (_fallbackSource) {
35
+ [_fallbackSource drawWithRect:self.bounds options:NSStringDrawingUsesLineFragmentOrigin context:nil];
36
+ }
30
37
  return;
38
+ }
31
39
  CGContextRef ctx = UIGraphicsGetCurrentContext();
32
40
  if (!ctx)
33
41
  return;
@@ -98,6 +106,7 @@
98
106
  color:config.mathColor
99
107
  bold:ENRMMathFontWeightIsBold(config.mathFontWeight)];
100
108
  _mathView.renderResult = result;
109
+ _mathView.fallbackSource = result ? nil : ENRMMathFallbackString(latex, @"$$", config.mathFontSize, config.mathColor);
101
110
 
102
111
  CGFloat padding = config.mathPadding;
103
112
  _mathView.frame = CGRectMake(padding, padding, ceil(result.width), ceil(result.totalHeight));
@@ -117,6 +126,11 @@
117
126
  - (UIContextMenuConfiguration *)contextMenuInteraction:(UIContextMenuInteraction *)interaction
118
127
  configurationForMenuAtLocation:(CGPoint)location
119
128
  {
129
+ // Returning nil is the UIKit-sanctioned way to suppress a context menu.
130
+ if (self.contextMenuHidden) {
131
+ return nil;
132
+ }
133
+
120
134
  return [UIContextMenuConfiguration
121
135
  configurationWithIdentifier:nil
122
136
  previewProvider:nil
@@ -141,6 +155,12 @@
141
155
  #if TARGET_OS_OSX
142
156
  - (NSMenu *)menuForEvent:(NSEvent *)event
143
157
  {
158
+ // This override never falls through to [super menuForEvent:], so nil fully
159
+ // suppresses the menu rather than restoring the AppKit default.
160
+ if (self.contextMenuHidden) {
161
+ return nil;
162
+ }
163
+
144
164
  NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
145
165
  [menu addItem:ENRMCreateMenuItem(self.copyLabel, ^{ [self copyLatexToPasteboard]; })];
146
166
  [menu addItem:ENRMCreateMenuItem(self.copyAsMarkdownLabel, ^{ [self copyMarkdownToPasteboard]; })];
@@ -166,9 +186,40 @@
166
186
  - (CGFloat)measureHeight:(CGFloat)maxWidth
167
187
  {
168
188
  CGFloat padding = self.config.mathPadding;
189
+ if (!_mathView.renderResult && _mathView.fallbackSource) {
190
+ CGFloat available = MAX(maxWidth - padding * 2, 1);
191
+ CGRect bounds = [_mathView.fallbackSource boundingRectWithSize:CGSizeMake(available, CGFLOAT_MAX)
192
+ options:NSStringDrawingUsesLineFragmentOrigin
193
+ context:nil];
194
+ return ceil(bounds.size.height) + padding * 2;
195
+ }
169
196
  return [self mathViewIntrinsicSize].height + padding * 2;
170
197
  }
171
198
 
199
+ + (CGFloat)measureHeightForLatex:(NSString *)latex config:(StyleConfig *)config maxWidth:(CGFloat)maxWidth
200
+ {
201
+ CGFloat padding = config.mathPadding;
202
+
203
+ ENRMRaTeXRenderResult *result = [ENRMRaTeXBridge parse:latex
204
+ displayMode:YES
205
+ fontSize:config.mathFontSize
206
+ color:config.mathColor
207
+ bold:ENRMMathFontWeightIsBold(config.mathFontWeight)];
208
+ if (result) {
209
+ return ceil(result.totalHeight) + padding * 2;
210
+ }
211
+
212
+ NSAttributedString *fallbackSource = ENRMMathFallbackString(latex, @"$$", config.mathFontSize, config.mathColor);
213
+ if (!fallbackSource) {
214
+ return 0;
215
+ }
216
+ CGFloat available = MAX(maxWidth - padding * 2, 1);
217
+ CGRect bounds = [fallbackSource boundingRectWithSize:CGSizeMake(available, CGFLOAT_MAX)
218
+ options:NSStringDrawingUsesLineFragmentOrigin
219
+ context:nil];
220
+ return ceil(bounds.size.height) + padding * 2;
221
+ }
222
+
172
223
  - (CGFloat)alignedOriginXForWidth:(CGFloat)formulaWidth inBounds:(CGFloat)boundsWidth padding:(CGFloat)padding
173
224
  {
174
225
  CGFloat available = boundsWidth - padding * 2;
@@ -188,6 +239,25 @@
188
239
  [super layoutSubviews];
189
240
 
190
241
  CGFloat padding = self.config.mathPadding;
242
+
243
+ if (!_mathView.renderResult && _mathView.fallbackSource) {
244
+ // Fallback source fills the available width and wraps; no horizontal scroll.
245
+ #if !TARGET_OS_OSX
246
+ _scrollView.frame = self.bounds;
247
+ _scrollView.contentSize = self.bounds.size;
248
+ _scrollView.contentOffset = CGPointZero;
249
+ _scrollView.scrollEnabled = NO;
250
+ #endif
251
+ _mathView.frame = CGRectMake(padding, padding, MAX(self.bounds.size.width - padding * 2, 1),
252
+ MAX(self.bounds.size.height - padding * 2, 1));
253
+ #if !TARGET_OS_OSX
254
+ [_mathView setNeedsDisplay];
255
+ #else
256
+ [_mathView setNeedsDisplay:YES];
257
+ #endif
258
+ return;
259
+ }
260
+
191
261
  CGSize intrinsicSize = [self mathViewIntrinsicSize];
192
262
  CGFloat contentWidth = intrinsicSize.width + padding * 2;
193
263
  CGFloat contentHeight = self.bounds.size.height;
@@ -18,6 +18,20 @@ typedef void (^TableLinkPressBlock)(NSString *url);
18
18
 
19
19
  - (CGFloat)measureHeight:(CGFloat)maxWidth;
20
20
 
21
+ /// View-free table height for shadow-node measurement (issue #550): renders
22
+ /// the cells' attributed strings and runs the same column/row layout the view
23
+ /// runs in `applyTableNode:`/`computeLayout` — shared statics, so measured and
24
+ /// rendered heights cannot drift — without creating any view. Safe on any
25
+ /// thread; the iOS counterpart of Android's
26
+ /// `TableContainerView.measureTableNodeHeight`. Table height is intrinsic
27
+ /// (content-sized columns, horizontal scroll), so no maxWidth parameter.
28
+ + (CGFloat)measureHeightForTableNode:(MarkdownASTNode *)tableNode
29
+ config:(StyleConfig *)config
30
+ allowFontScaling:(BOOL)allowFontScaling
31
+ maxFontSizeMultiplier:(CGFloat)maxFontSizeMultiplier
32
+ writingDirectionMode:(ENRMWritingDirectionMode)writingDirectionMode
33
+ resolvedLayoutDirection:(NSWritingDirection)resolvedLayoutDirection;
34
+
21
35
  @property (nonatomic, strong) StyleConfig *config;
22
36
 
23
37
  @property (nonatomic, assign) BOOL allowFontScaling;
@@ -38,6 +52,10 @@ typedef void (^TableLinkPressBlock)(NSString *url);
38
52
  @property (nonatomic, copy, nullable, getter=menuCopyLabel) NSString *copyLabel;
39
53
  @property (nonatomic, copy, nullable, getter=menuCopyAsMarkdownLabel) NSString *copyAsMarkdownLabel;
40
54
 
55
+ /// Suppresses the long-press copy menu on this block. Mirrors the
56
+ /// `contextMenuHidden` prop; selection and link handling are unaffected.
57
+ @property (nonatomic, assign) BOOL contextMenuHidden;
58
+
41
59
  @property (nonatomic, readonly) NSUInteger rowCount;
42
60
 
43
61
  - (void)animateNewRowsFromPreviousCount:(NSUInteger)previousRowCount duration:(NSTimeInterval)duration;
@@ -28,6 +28,184 @@
28
28
  @implementation TableCellData
29
29
  @end
30
30
 
31
+ // Cell rendering and layout are view-free statics so the instance path
32
+ // (applyTableNode:/computeLayout) and the shadow-measurement class method
33
+ // (+measureHeightForTableNode:...) share one implementation and cannot drift
34
+ // (issue #550).
35
+
36
+ static NSTextAlignment ENRMTableTextAlignmentFromString(NSString *align)
37
+ {
38
+ if ([align isEqualToString:@"center"])
39
+ return NSTextAlignmentCenter;
40
+ if ([align isEqualToString:@"right"])
41
+ return NSTextAlignmentRight;
42
+ return NSTextAlignmentLeft;
43
+ }
44
+
45
+ static NSString *ENRMTablePlainTextFromNode(MarkdownASTNode *node)
46
+ {
47
+ if (!node)
48
+ return @"";
49
+ NSMutableString *buffer = [node.content mutableCopy] ?: [NSMutableString string];
50
+ for (MarkdownASTNode *child in node.children) {
51
+ [buffer appendString:ENRMTablePlainTextFromNode(child)];
52
+ }
53
+ return [buffer copy];
54
+ }
55
+
56
+ static StyleConfig *ENRMTableCellConfig(StyleConfig *config, BOOL isHeader)
57
+ {
58
+ StyleConfig *cellConfig = [config copy];
59
+
60
+ [cellConfig setParagraphFontSize:config.tableFontSize];
61
+ NSString *headerFamily =
62
+ config.tableHeaderFontFamily.length > 0 ? config.tableHeaderFontFamily : config.tableFontFamily;
63
+ [cellConfig setParagraphFontFamily:isHeader ? headerFamily : config.tableFontFamily];
64
+ [cellConfig setParagraphFontWeight:isHeader ? @"bold" : config.tableFontWeight];
65
+ [cellConfig setParagraphColor:isHeader ? config.tableHeaderTextColor : config.tableColor];
66
+ [cellConfig setParagraphLineHeight:config.tableLineHeight];
67
+
68
+ [cellConfig setParagraphMarginTop:0];
69
+ [cellConfig setParagraphMarginBottom:0];
70
+
71
+ return cellConfig;
72
+ }
73
+
74
+ static NSMutableAttributedString *ENRMTableRenderCellNode(MarkdownASTNode *cellNode, StyleConfig *cellConfig,
75
+ NSTextAlignment alignment, BOOL allowFontScaling,
76
+ CGFloat maxFontSizeMultiplier,
77
+ ENRMWritingDirectionMode writingDirectionMode,
78
+ NSWritingDirection resolvedLayoutDirection)
79
+ {
80
+ MarkdownASTNode *temporaryRoot = [[MarkdownASTNode alloc] initWithType:MarkdownNodeTypeDocument];
81
+ for (MarkdownASTNode *child in cellNode.children) {
82
+ [temporaryRoot addChild:child];
83
+ }
84
+
85
+ AttributedRenderer *renderer = [[AttributedRenderer alloc] initWithConfig:cellConfig];
86
+ RenderContext *context = [RenderContext new];
87
+ context.allowFontScaling = allowFontScaling;
88
+ context.maxFontSizeMultiplier = maxFontSizeMultiplier;
89
+
90
+ NSMutableAttributedString *attributedText = [renderer renderRoot:temporaryRoot context:context];
91
+
92
+ [context applyLinkAttributesToString:attributedText];
93
+
94
+ ENRMApplyWritingDirectionMode(attributedText, writingDirectionMode, resolvedLayoutDirection);
95
+
96
+ if (alignment != NSTextAlignmentLeft && attributedText.length > 0) {
97
+ NSRange fullRange = NSMakeRange(0, attributedText.length);
98
+ [attributedText
99
+ enumerateAttribute:NSParagraphStyleAttributeName
100
+ inRange:fullRange
101
+ options:0
102
+ usingBlock:^(NSParagraphStyle *paragraphStyle, NSRange range, BOOL *stop) {
103
+ NSMutableParagraphStyle *mutableStyle =
104
+ paragraphStyle ? [paragraphStyle mutableCopy] : [[NSMutableParagraphStyle alloc] init];
105
+ mutableStyle.alignment = alignment;
106
+ [attributedText addAttribute:NSParagraphStyleAttributeName value:mutableStyle range:range];
107
+ }];
108
+ }
109
+
110
+ return attributedText;
111
+ }
112
+
113
+ static NSArray<NSArray<TableCellData *> *> *ENRMTableBuildRows(MarkdownASTNode *tableNode, StyleConfig *config,
114
+ BOOL allowFontScaling, CGFloat maxFontSizeMultiplier,
115
+ ENRMWritingDirectionMode writingDirectionMode,
116
+ NSWritingDirection resolvedLayoutDirection,
117
+ NSUInteger *outColCount)
118
+ {
119
+ StyleConfig *headerCellConfig = ENRMTableCellConfig(config, YES);
120
+ StyleConfig *bodyCellConfig = ENRMTableCellConfig(config, NO);
121
+
122
+ NSMutableArray *allRows = [NSMutableArray array];
123
+ NSUInteger colCount = 0;
124
+
125
+ for (MarkdownASTNode *section in tableNode.children) {
126
+ BOOL isSectionHead = (section.type == MarkdownNodeTypeTableHead);
127
+
128
+ for (MarkdownASTNode *rowNode in section.children) {
129
+ if (rowNode.type != MarkdownNodeTypeTableRow)
130
+ continue;
131
+
132
+ NSMutableArray<TableCellData *> *rowCells = [NSMutableArray array];
133
+ for (MarkdownASTNode *cellNode in rowNode.children) {
134
+ TableCellData *cell = [[TableCellData alloc] init];
135
+ cell.isHeader = isSectionHead || (cellNode.type == MarkdownNodeTypeTableHeaderCell);
136
+ cell.alignment = ENRMTableTextAlignmentFromString(cellNode.attributes[@"align"]);
137
+ cell.plainText = ENRMTablePlainTextFromNode(cellNode);
138
+ cell.markdownText = markdownFromASTNodeChildren(cellNode);
139
+
140
+ StyleConfig *cellConfig = cell.isHeader ? headerCellConfig : bodyCellConfig;
141
+ cell.attributedText =
142
+ ENRMTableRenderCellNode(cellNode, cellConfig, cell.alignment, allowFontScaling, maxFontSizeMultiplier,
143
+ writingDirectionMode, resolvedLayoutDirection);
144
+ [rowCells addObject:cell];
145
+ }
146
+ colCount = MAX(colCount, rowCells.count);
147
+ [allRows addObject:rowCells];
148
+ }
149
+ }
150
+
151
+ if (outColCount != NULL) {
152
+ *outColCount = colCount;
153
+ }
154
+ return [allRows copy];
155
+ }
156
+
157
+ static void ENRMTableComputeLayout(NSArray<NSArray<TableCellData *> *> *rows, NSUInteger colCount, StyleConfig *config,
158
+ CGFloat borderWidth, NSMutableArray<NSNumber *> *_Nullable *_Nullable outColWidths,
159
+ NSMutableArray<NSNumber *> *_Nullable *_Nullable outRowHeights,
160
+ CGFloat *_Nullable outTotalWidth, CGFloat *_Nullable outTotalHeight)
161
+ {
162
+ // TODO: Consider making minColumnWidth / maxColumnWidth configurable via style props
163
+ const CGFloat minimumColumnWidth = 60.0;
164
+ const CGFloat maximumColumnWidth = 300.0;
165
+ const CGFloat horizontalPadding = config.tableCellPaddingHorizontal * 2;
166
+ const CGFloat verticalPadding = config.tableCellPaddingVertical * 2;
167
+
168
+ NSMutableArray<NSNumber *> *colWidths = [NSMutableArray arrayWithCapacity:colCount];
169
+ for (NSUInteger i = 0; i < colCount; i++)
170
+ [colWidths addObject:@0];
171
+
172
+ for (NSArray<TableCellData *> *row in rows) {
173
+ for (NSUInteger column = 0; column < row.count; column++) {
174
+ CGRect boundingRect = [row[column].attributedText
175
+ boundingRectWithSize:CGSizeMake(maximumColumnWidth, CGFLOAT_MAX)
176
+ options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
177
+ context:nil];
178
+ CGFloat width = MIN(MAX(ceil(boundingRect.size.width) + horizontalPadding, minimumColumnWidth),
179
+ maximumColumnWidth + horizontalPadding);
180
+ if (width > [colWidths[column] doubleValue])
181
+ colWidths[column] = @(width);
182
+ }
183
+ }
184
+
185
+ NSMutableArray<NSNumber *> *rowHeights = [NSMutableArray arrayWithCapacity:rows.count];
186
+ for (NSArray<TableCellData *> *row in rows) {
187
+ CGFloat maxHeight = 0;
188
+ for (NSUInteger column = 0; column < row.count; column++) {
189
+ CGFloat availableWidth = [colWidths[column] doubleValue] - horizontalPadding;
190
+ CGRect boundingRect = [row[column].attributedText
191
+ boundingRectWithSize:CGSizeMake(availableWidth, CGFLOAT_MAX)
192
+ options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
193
+ context:nil];
194
+ maxHeight = MAX(maxHeight, ceil(boundingRect.size.height) + verticalPadding);
195
+ }
196
+ [rowHeights addObject:@(maxHeight)];
197
+ }
198
+
199
+ if (outColWidths != NULL)
200
+ *outColWidths = colWidths;
201
+ if (outRowHeights != NULL)
202
+ *outRowHeights = rowHeights;
203
+ if (outTotalWidth != NULL)
204
+ *outTotalWidth = [[colWidths valueForKeyPath:@"@sum.self"] doubleValue] + borderWidth;
205
+ if (outTotalHeight != NULL)
206
+ *outTotalHeight = [[rowHeights valueForKeyPath:@"@sum.self"] doubleValue] + borderWidth;
207
+ }
208
+
31
209
  #if !TARGET_OS_OSX
32
210
  @interface TableContainerView () <UIContextMenuInteractionDelegate>
33
211
  @end
@@ -46,7 +224,6 @@
46
224
  NSMutableArray<NSNumber *> *_rowHeights;
47
225
  CGFloat _totalTableWidth;
48
226
  CGFloat _totalTableHeight;
49
- CGFloat _borderWidth;
50
227
 
51
228
  NSString *_cachedMarkdown;
52
229
 
@@ -58,7 +235,6 @@
58
235
  self = [super initWithFrame:CGRectZero];
59
236
  if (self) {
60
237
  _config = config;
61
- _borderWidth = config.tableBorderWidth;
62
238
  _allowFontScaling = YES;
63
239
  _maxFontSizeMultiplier = 0;
64
240
  _enableLinkPreview = YES;
@@ -88,11 +264,12 @@
88
264
  // a single drawRect: pass (no subview / layer compositing issues).
89
265
  ENRMTableGridView *gridView = [[ENRMTableGridView alloc] initWithFrame:CGRectZero];
90
266
  __weak TableContainerView *weakSelf = self;
91
- gridView.menuProvider = ^NSMenu *
92
- {
267
+ gridView.menuProvider = ^NSMenu * {
93
268
  TableContainerView *strongSelf = weakSelf;
94
269
  if (!strongSelf)
95
270
  return nil;
271
+ if (strongSelf.contextMenuHidden)
272
+ return nil;
96
273
  NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
97
274
  [menu addItem:ENRMCreateMenuItem(strongSelf.copyLabel, ^{ [strongSelf copyTableToPasteboard]; })];
98
275
  [menu addItem:ENRMCreateMenuItem(strongSelf.copyAsMarkdownLabel, ^{ [strongSelf copyMarkdownToPasteboard]; })];
@@ -120,74 +297,6 @@
120
297
  #endif
121
298
  }
122
299
 
123
- - (StyleConfig *)cellConfigForHeader:(BOOL)isHeader
124
- {
125
- StyleConfig *cellConfig = [self.config copy];
126
-
127
- [cellConfig setParagraphFontSize:self.config.tableFontSize];
128
- NSString *headerFamily =
129
- self.config.tableHeaderFontFamily.length > 0 ? self.config.tableHeaderFontFamily : self.config.tableFontFamily;
130
- [cellConfig setParagraphFontFamily:isHeader ? headerFamily : self.config.tableFontFamily];
131
- [cellConfig setParagraphFontWeight:isHeader ? @"bold" : self.config.tableFontWeight];
132
- [cellConfig setParagraphColor:isHeader ? self.config.tableHeaderTextColor : self.config.tableColor];
133
- [cellConfig setParagraphLineHeight:self.config.tableLineHeight];
134
-
135
- [cellConfig setParagraphMarginTop:0];
136
- [cellConfig setParagraphMarginBottom:0];
137
-
138
- return cellConfig;
139
- }
140
-
141
- - (NSMutableAttributedString *)renderCellNode:(MarkdownASTNode *)cellNode
142
- isHeader:(BOOL)isHeader
143
- cellConfig:(StyleConfig *)cellConfig
144
- alignment:(NSTextAlignment)alignment
145
- {
146
-
147
- MarkdownASTNode *temporaryRoot = [[MarkdownASTNode alloc] initWithType:MarkdownNodeTypeDocument];
148
- for (MarkdownASTNode *child in cellNode.children) {
149
- [temporaryRoot addChild:child];
150
- }
151
-
152
- AttributedRenderer *renderer = [[AttributedRenderer alloc] initWithConfig:cellConfig];
153
- RenderContext *context = [RenderContext new];
154
- context.allowFontScaling = self.allowFontScaling;
155
- context.maxFontSizeMultiplier = self.maxFontSizeMultiplier;
156
-
157
- NSMutableAttributedString *attributedText = [renderer renderRoot:temporaryRoot context:context];
158
-
159
- [context applyLinkAttributesToString:attributedText];
160
-
161
- ENRMApplyWritingDirectionMode(attributedText, _writingDirectionMode, _resolvedLayoutDirection);
162
-
163
- if (alignment != NSTextAlignmentLeft && attributedText.length > 0) {
164
- NSRange fullRange = NSMakeRange(0, attributedText.length);
165
- [attributedText
166
- enumerateAttribute:NSParagraphStyleAttributeName
167
- inRange:fullRange
168
- options:0
169
- usingBlock:^(NSParagraphStyle *paragraphStyle, NSRange range, BOOL *stop) {
170
- NSMutableParagraphStyle *mutableStyle =
171
- paragraphStyle ? [paragraphStyle mutableCopy] : [[NSMutableParagraphStyle alloc] init];
172
- mutableStyle.alignment = alignment;
173
- [attributedText addAttribute:NSParagraphStyleAttributeName value:mutableStyle range:range];
174
- }];
175
- }
176
-
177
- return attributedText;
178
- }
179
-
180
- - (NSString *)extractPlainTextFromNode:(MarkdownASTNode *)node
181
- {
182
- if (!node)
183
- return @"";
184
- NSMutableString *buffer = [node.content mutableCopy] ?: [NSMutableString string];
185
- for (MarkdownASTNode *child in node.children) {
186
- [buffer appendString:[self extractPlainTextFromNode:child]];
187
- }
188
- return [buffer copy];
189
- }
190
-
191
300
  - (NSUInteger)rowCount
192
301
  {
193
302
  return _rows.count;
@@ -212,96 +321,47 @@
212
321
  {
213
322
  [[_gridContainer subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
214
323
 
215
- StyleConfig *headerCellConfig = [self cellConfigForHeader:YES];
216
- StyleConfig *bodyCellConfig = [self cellConfigForHeader:NO];
217
-
218
- NSMutableArray *allRows = [NSMutableArray array];
219
- _colCount = 0;
220
-
221
- for (MarkdownASTNode *section in tableNode.children) {
222
- BOOL isSectionHead = (section.type == MarkdownNodeTypeTableHead);
223
-
224
- for (MarkdownASTNode *rowNode in section.children) {
225
- if (rowNode.type != MarkdownNodeTypeTableRow)
226
- continue;
227
-
228
- NSMutableArray<TableCellData *> *rowCells = [NSMutableArray array];
229
- for (MarkdownASTNode *cellNode in rowNode.children) {
230
- TableCellData *cell = [[TableCellData alloc] init];
231
- cell.isHeader = isSectionHead || (cellNode.type == MarkdownNodeTypeTableHeaderCell);
232
- cell.alignment = [self textAlignmentFromString:cellNode.attributes[@"align"]];
233
- cell.plainText = [self extractPlainTextFromNode:cellNode];
234
- cell.markdownText = markdownFromASTNodeChildren(cellNode);
235
-
236
- StyleConfig *cellConfig = cell.isHeader ? headerCellConfig : bodyCellConfig;
237
- cell.attributedText = [self renderCellNode:cellNode
238
- isHeader:cell.isHeader
239
- cellConfig:cellConfig
240
- alignment:cell.alignment];
241
- [rowCells addObject:cell];
242
- }
243
- _colCount = MAX(_colCount, rowCells.count);
244
- [allRows addObject:rowCells];
245
- }
246
- }
247
-
248
- _rows = [allRows copy];
324
+ NSUInteger colCount = 0;
325
+ _rows = ENRMTableBuildRows(tableNode, self.config, self.allowFontScaling, self.maxFontSizeMultiplier,
326
+ _writingDirectionMode, _resolvedLayoutDirection, &colCount);
327
+ _colCount = colCount;
249
328
  _cachedMarkdown = [self buildMarkdownFromRows];
250
329
  _cachedAccessibilityElements = nil;
251
330
  [self computeLayout];
252
331
  [self renderGrid];
253
332
  }
254
333
 
255
- - (NSTextAlignment)textAlignmentFromString:(NSString *)align
334
+ - (void)computeLayout
256
335
  {
257
- if ([align isEqualToString:@"center"])
258
- return NSTextAlignmentCenter;
259
- if ([align isEqualToString:@"right"])
260
- return NSTextAlignmentRight;
261
- return NSTextAlignmentLeft;
336
+ NSMutableArray<NSNumber *> *colWidths = nil;
337
+ NSMutableArray<NSNumber *> *rowHeights = nil;
338
+ CGFloat totalWidth = 0;
339
+ CGFloat totalHeight = 0;
340
+ ENRMTableComputeLayout(_rows, _colCount, self.config, self.config.tableBorderWidth, &colWidths, &rowHeights,
341
+ &totalWidth, &totalHeight);
342
+ _colWidths = colWidths;
343
+ _rowHeights = rowHeights;
344
+ _totalTableWidth = totalWidth;
345
+ _totalTableHeight = totalHeight;
262
346
  }
263
347
 
264
- - (void)computeLayout
348
+ + (CGFloat)measureHeightForTableNode:(MarkdownASTNode *)tableNode
349
+ config:(StyleConfig *)config
350
+ allowFontScaling:(BOOL)allowFontScaling
351
+ maxFontSizeMultiplier:(CGFloat)maxFontSizeMultiplier
352
+ writingDirectionMode:(ENRMWritingDirectionMode)writingDirectionMode
353
+ resolvedLayoutDirection:(NSWritingDirection)resolvedLayoutDirection
265
354
  {
266
- // TODO: Consider making minColumnWidth / maxColumnWidth configurable via style props
267
- const CGFloat minimumColumnWidth = 60.0;
268
- const CGFloat maximumColumnWidth = 300.0;
269
- const CGFloat horizontalPadding = self.config.tableCellPaddingHorizontal * 2;
270
- const CGFloat verticalPadding = self.config.tableCellPaddingVertical * 2;
271
-
272
- _colWidths = [NSMutableArray arrayWithCapacity:_colCount];
273
- for (NSUInteger i = 0; i < _colCount; i++)
274
- [_colWidths addObject:@0];
275
-
276
- for (NSArray<TableCellData *> *row in _rows) {
277
- for (NSUInteger column = 0; column < row.count; column++) {
278
- CGRect boundingRect = [row[column].attributedText
279
- boundingRectWithSize:CGSizeMake(maximumColumnWidth, CGFLOAT_MAX)
280
- options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
281
- context:nil];
282
- CGFloat width = MIN(MAX(ceil(boundingRect.size.width) + horizontalPadding, minimumColumnWidth),
283
- maximumColumnWidth + horizontalPadding);
284
- if (width > [_colWidths[column] doubleValue])
285
- _colWidths[column] = @(width);
286
- }
287
- }
288
-
289
- _rowHeights = [NSMutableArray arrayWithCapacity:_rows.count];
290
- for (NSArray<TableCellData *> *row in _rows) {
291
- CGFloat maxHeight = 0;
292
- for (NSUInteger column = 0; column < row.count; column++) {
293
- CGFloat availableWidth = [_colWidths[column] doubleValue] - horizontalPadding;
294
- CGRect boundingRect = [row[column].attributedText
295
- boundingRectWithSize:CGSizeMake(availableWidth, CGFLOAT_MAX)
296
- options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
297
- context:nil];
298
- maxHeight = MAX(maxHeight, ceil(boundingRect.size.height) + verticalPadding);
299
- }
300
- [_rowHeights addObject:@(maxHeight)];
301
- }
355
+ NSUInteger colCount = 0;
356
+ NSArray<NSArray<TableCellData *> *> *rows =
357
+ ENRMTableBuildRows(tableNode, config, allowFontScaling, maxFontSizeMultiplier, writingDirectionMode,
358
+ resolvedLayoutDirection, &colCount);
359
+ if (rows.count == 0)
360
+ return 0;
302
361
 
303
- _totalTableWidth = [[_colWidths valueForKeyPath:@"@sum.self"] doubleValue] + _borderWidth;
304
- _totalTableHeight = [[_rowHeights valueForKeyPath:@"@sum.self"] doubleValue] + _borderWidth;
362
+ CGFloat totalHeight = 0;
363
+ ENRMTableComputeLayout(rows, colCount, config, config.tableBorderWidth, NULL, NULL, NULL, &totalHeight);
364
+ return totalHeight;
305
365
  }
306
366
 
307
367
  - (void)renderGrid
@@ -357,7 +417,7 @@
357
417
  columnWidths:_colWidths
358
418
  rowHeights:_rowHeights
359
419
  borderColor:self.config.tableBorderColor
360
- borderWidth:_borderWidth
420
+ borderWidth:self.config.tableBorderWidth
361
421
  horizontalCellPadding:self.config.tableCellPaddingHorizontal
362
422
  verticalCellPadding:self.config.tableCellPaddingVertical
363
423
  cornerRadius:self.config.tableBorderRadius];
@@ -392,7 +452,7 @@
392
452
  columnWidths:_colWidths
393
453
  rowHeights:_rowHeights
394
454
  borderColor:self.config.tableBorderColor
395
- borderWidth:_borderWidth
455
+ borderWidth:self.config.tableBorderWidth
396
456
  horizontalCellPadding:self.config.tableCellPaddingHorizontal
397
457
  verticalCellPadding:self.config.tableCellPaddingVertical
398
458
  cornerRadius:self.config.tableBorderRadius];
@@ -403,6 +463,11 @@
403
463
  - (UIContextMenuConfiguration *)contextMenuInteraction:(UIContextMenuInteraction *)interaction
404
464
  configurationForMenuAtLocation:(CGPoint)location
405
465
  {
466
+ // Returning nil is the UIKit-sanctioned way to suppress a context menu.
467
+ if (self.contextMenuHidden) {
468
+ return nil;
469
+ }
470
+
406
471
  return [UIContextMenuConfiguration
407
472
  configurationWithIdentifier:nil
408
473
  previewProvider:nil
@@ -550,19 +615,54 @@
550
615
  return _totalTableHeight;
551
616
  }
552
617
 
618
+ - (CGFloat)alignOffsetForFreeSpace:(CGFloat)freeSpace
619
+ {
620
+ if (freeSpace <= 0)
621
+ return 0;
622
+ NSString *align = self.config.tableAlign;
623
+ if ([align isEqualToString:@"center"])
624
+ return freeSpace / 2;
625
+ if ([align isEqualToString:@"right"])
626
+ return freeSpace;
627
+ return 0;
628
+ }
629
+
553
630
  - (void)layoutSubviews
554
631
  {
555
632
  [super layoutSubviews];
556
633
  _scrollView.frame = self.bounds;
557
634
  #if !TARGET_OS_OSX
558
- _scrollView.contentSize = CGSizeMake(MAX(_totalTableWidth, self.bounds.size.width), _totalTableHeight);
559
- _scrollView.scrollEnabled = (_totalTableWidth > self.bounds.size.width);
560
- _gridContainer.frame = CGRectMake(0, 0, _totalTableWidth, _totalTableHeight);
635
+ CGFloat overhang = MAX(self.config.tableHorizontalOverflow, 0);
636
+ CGFloat containerWidth = self.bounds.size.width;
637
+ BOOL tableOverflows = (overhang > 0 && _totalTableWidth > containerWidth);
638
+
639
+ if (tableOverflows) {
640
+ UIEdgeInsets inset = UIEdgeInsetsMake(0, overhang, 0, overhang);
641
+ if (!UIEdgeInsetsEqualToEdgeInsets(_scrollView.contentInset, inset)) {
642
+ _scrollView.contentInset = inset;
643
+ _scrollView.contentOffset = CGPointMake(-overhang, 0);
644
+ }
645
+ _scrollView.contentSize = CGSizeMake(_totalTableWidth, _totalTableHeight);
646
+ _scrollView.scrollEnabled = YES;
647
+ _gridContainer.frame = CGRectMake(0, 0, _totalTableWidth, _totalTableHeight);
648
+ } else {
649
+ CGFloat alignOffset = [self alignOffsetForFreeSpace:containerWidth - overhang * 2 - _totalTableWidth];
650
+ _scrollView.contentInset = UIEdgeInsetsZero;
651
+ _scrollView.contentOffset = CGPointZero;
652
+ _scrollView.contentSize = CGSizeMake(MAX(_totalTableWidth, containerWidth), _totalTableHeight);
653
+ _scrollView.scrollEnabled = (_totalTableWidth > containerWidth);
654
+ _gridContainer.frame = CGRectMake(overhang + alignOffset, 0, _totalTableWidth, _totalTableHeight);
655
+ }
561
656
  #else
562
- // For NSScrollView+documentView, the scrollable content area is determined by
563
- // the documentView's frame. No contentSize property to set.
564
- if (_totalTableWidth > 0 && _totalTableHeight > 0) {
657
+ CGFloat overhang = MAX(self.config.tableHorizontalOverflow, 0);
658
+ CGFloat containerWidth = self.bounds.size.width;
659
+ BOOL tableOverflows = (overhang > 0 && _totalTableWidth > containerWidth);
660
+
661
+ if (tableOverflows) {
565
662
  _gridContainer.frame = CGRectMake(0, 0, _totalTableWidth, _totalTableHeight);
663
+ } else if (_totalTableWidth > 0 && _totalTableHeight > 0) {
664
+ CGFloat alignOffset = [self alignOffsetForFreeSpace:containerWidth - overhang * 2 - _totalTableWidth];
665
+ _gridContainer.frame = CGRectMake(overhang + alignOffset, 0, _totalTableWidth, _totalTableHeight);
566
666
  }
567
667
  #endif
568
668
  }
package/jest.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './src/jest';
package/jest.js ADDED
@@ -0,0 +1,5 @@
1
+ 'use strict';
2
+
3
+ // Subpath entry for `require('react-native-enriched-markdown-scaffold/jest')`.
4
+ // Re-exports the compiled mock (built from `src/jest` by react-native-builder-bob).
5
+ module.exports = require('./lib/module/jest');