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