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
|
@@ -13,6 +13,13 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
13
13
|
- (void)renderMarkdownSynchronously:(NSString *)markdownString;
|
|
14
14
|
- (BOOL)hasRenderedMarkdown:(NSString *)markdown;
|
|
15
15
|
- (BOOL)hasRenderedWithStyleFingerprint:(size_t)fingerprint;
|
|
16
|
+
|
|
17
|
+
/// Size last committed by Fabric via `updateLayoutMetrics:`, readable from
|
|
18
|
+
/// any thread without blocking (issue #550: the shadow-node measure path must
|
|
19
|
+
/// never wait on the main thread, and reading `bounds` off-main is unsafe).
|
|
20
|
+
/// Backed by a single lock-free atomic, so the pair can't tear. Returns
|
|
21
|
+
/// CGSizeZero until the first layout is committed.
|
|
22
|
+
- (CGSize)lastCommittedLayoutSize;
|
|
16
23
|
@end
|
|
17
24
|
|
|
18
25
|
NS_ASSUME_NONNULL_END
|
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
#import "ContextMenuUtils.h"
|
|
4
4
|
#import "ENRMAccessibilityLabels.h"
|
|
5
5
|
#import "ENRMAsyncRenderCoordinator.h"
|
|
6
|
+
#import "ENRMAtomicSize.h"
|
|
6
7
|
#import "ENRMContextMenuTextView+macOS.h"
|
|
7
8
|
#import "ENRMImageAttachment.h"
|
|
9
|
+
#import "ENRMLinkLayout.h"
|
|
8
10
|
#import "ENRMMarkdownParser.h"
|
|
11
|
+
#import "ENRMSelectionChange.h"
|
|
9
12
|
#import "ENRMSpoilerOverlayManager.h"
|
|
10
13
|
#import "ENRMSpoilerTapUtils.h"
|
|
11
14
|
#import "ENRMTailFadeInAnimator.h"
|
|
@@ -17,12 +20,14 @@
|
|
|
17
20
|
#import "FontScaleObserver.h"
|
|
18
21
|
#import "FontUtils.h"
|
|
19
22
|
#import "HeightUpdateUtils.h"
|
|
23
|
+
#import "ImageRequestHeaderUtils.h"
|
|
20
24
|
#import "LinkTapUtils.h"
|
|
21
25
|
#import "MarkdownASTNode.h"
|
|
22
26
|
#import "MarkdownAccessibilityElementBuilder.h"
|
|
23
27
|
#import "MarkdownExtractor.h"
|
|
24
28
|
#import "MeasurementCache.h"
|
|
25
29
|
#import "ParagraphStyleUtils.h"
|
|
30
|
+
#import "PasteboardUtils.h"
|
|
26
31
|
#import "RuntimeKeys.h"
|
|
27
32
|
#import "SelectionColorUtils.h"
|
|
28
33
|
#import "StylePropsUtils.h"
|
|
@@ -45,8 +50,8 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
45
50
|
ENRMDirtyRender = 1 << 0,
|
|
46
51
|
};
|
|
47
52
|
|
|
48
|
-
@interface EnrichedMarkdownText () <RCTEnrichedMarkdownTextViewProtocol, UITextViewDelegate>
|
|
49
|
-
|
|
53
|
+
@interface EnrichedMarkdownText () <RCTEnrichedMarkdownTextViewProtocol, UITextViewDelegate, ENRMImageLayoutObserver>
|
|
54
|
+
+ (ENRMMd4cFlags *)flagsFromProps:(const EnrichedMarkdownTextMd4cFlagsStruct &)props;
|
|
50
55
|
- (void)setupTextView;
|
|
51
56
|
- (void)renderMarkdownContent:(NSString *)markdownString;
|
|
52
57
|
- (void)applyRenderedText:(NSMutableAttributedString *)attributedText;
|
|
@@ -54,11 +59,13 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
54
59
|
- (void)setupLayoutManager;
|
|
55
60
|
- (void)emitLinkPress:(NSString *)url;
|
|
56
61
|
- (void)emitLinkLongPress:(NSString *)url;
|
|
62
|
+
- (void)emitLinkLayoutIfNeeded;
|
|
57
63
|
- (void)emitTaskListItemPress:(NSInteger)index checked:(BOOL)checked text:(NSString *)text;
|
|
58
64
|
- (void)emitContextMenuItemPress:(NSString *)itemText
|
|
59
65
|
selectedText:(NSString *)selectedText
|
|
60
66
|
selectionStart:(NSUInteger)selectionStart
|
|
61
67
|
selectionEnd:(NSUInteger)selectionEnd;
|
|
68
|
+
- (void)emitCopyRequest:(NSString *)source markdown:(NSString *)markdown text:(NSString *)text whole:(BOOL)whole;
|
|
62
69
|
@end
|
|
63
70
|
|
|
64
71
|
@implementation EnrichedMarkdownText {
|
|
@@ -80,6 +87,9 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
80
87
|
CGFloat _lastElementMarginBottom;
|
|
81
88
|
BOOL _allowTrailingMargin;
|
|
82
89
|
BOOL _enableLinkPreview;
|
|
90
|
+
BOOL _linkLongPressSelects;
|
|
91
|
+
BOOL _enableTaskListItemToggle;
|
|
92
|
+
BOOL _contextMenuHidden;
|
|
83
93
|
BOOL _streamingAnimation;
|
|
84
94
|
BOOL _forceHeightUpdateOnNextRender;
|
|
85
95
|
|
|
@@ -105,12 +115,22 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
105
115
|
|
|
106
116
|
ENRMSpoilerOverlayManager *_spoilerManager;
|
|
107
117
|
|
|
118
|
+
BOOL _emitLinkLayout;
|
|
119
|
+
NSArray<NSDictionary *> *_lastLinkLayout;
|
|
120
|
+
|
|
121
|
+
ENRMSelectionChangeReporter *_selectionReporter;
|
|
122
|
+
#if !TARGET_OS_OSX
|
|
123
|
+
ENRMSelectionGestureTracker *_selectionGestures;
|
|
124
|
+
#endif
|
|
125
|
+
|
|
108
126
|
NSLineBreakStrategy _lineBreakStrategy;
|
|
109
127
|
|
|
110
128
|
ENRMWritingDirectionMode _writingDirectionMode;
|
|
111
129
|
NSWritingDirection _resolvedLayoutDirection;
|
|
112
130
|
|
|
113
131
|
ENRMDirtyFlags _dirtyFlags;
|
|
132
|
+
|
|
133
|
+
ENRMAtomicSize _lastCommittedSize;
|
|
114
134
|
}
|
|
115
135
|
|
|
116
136
|
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
|
@@ -118,6 +138,18 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
118
138
|
return concreteComponentDescriptorProvider<EnrichedMarkdownTextComponentDescriptor>();
|
|
119
139
|
}
|
|
120
140
|
|
|
141
|
+
+ (ENRMMd4cFlags *)flagsFromProps:(const EnrichedMarkdownTextMd4cFlagsStruct &)props
|
|
142
|
+
{
|
|
143
|
+
ENRMMd4cFlags *flags = [ENRMMd4cFlags defaultFlags];
|
|
144
|
+
flags.underline = props.underline;
|
|
145
|
+
flags.superscript = props.superscript;
|
|
146
|
+
flags.subscript = props.subscript;
|
|
147
|
+
flags.latexMath = props.latexMath;
|
|
148
|
+
flags.highlight = props.highlight;
|
|
149
|
+
flags.hardSoftBreaks = props.hardSoftBreaks;
|
|
150
|
+
return flags;
|
|
151
|
+
}
|
|
152
|
+
|
|
121
153
|
#pragma mark - Measuring and State
|
|
122
154
|
|
|
123
155
|
- (CGSize)measureSize:(CGFloat)maxWidth
|
|
@@ -130,6 +162,11 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
130
162
|
return size;
|
|
131
163
|
}
|
|
132
164
|
|
|
165
|
+
- (CGSize)lastCommittedLayoutSize
|
|
166
|
+
{
|
|
167
|
+
return _lastCommittedSize.load();
|
|
168
|
+
}
|
|
169
|
+
|
|
133
170
|
- (BOOL)hasRenderedMarkdown:(NSString *)markdown
|
|
134
171
|
{
|
|
135
172
|
return _renderedMarkdown != nil && [_renderedMarkdown isEqualToString:markdown];
|
|
@@ -158,6 +195,11 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
158
195
|
{
|
|
159
196
|
[super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
|
|
160
197
|
|
|
198
|
+
_lastCommittedSize.store(CGSizeMake(layoutMetrics.frame.size.width, layoutMetrics.frame.size.height));
|
|
199
|
+
#if TARGET_OS_OSX
|
|
200
|
+
[self emitLinkLayoutIfNeeded];
|
|
201
|
+
#endif
|
|
202
|
+
|
|
161
203
|
NSWritingDirection resolved = _resolvedLayoutDirection;
|
|
162
204
|
if (layoutMetrics.layoutDirection == LayoutDirection::RightToLeft) {
|
|
163
205
|
resolved = NSWritingDirectionRightToLeft;
|
|
@@ -178,44 +220,22 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
178
220
|
ENRMRequestHeightUpdate<EnrichedMarkdownTextState>(_state, _heightUpdateCounter, self);
|
|
179
221
|
}
|
|
180
222
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
/// baselines cannot drift apart.
|
|
190
|
-
///
|
|
191
|
-
/// Requires `_fontScaleObserver` to already exist.
|
|
192
|
-
- (void)resetPropDerivedState
|
|
193
|
-
{
|
|
194
|
-
// Discarded rather than cleared field-by-field: the style diff can only clear a
|
|
195
|
-
// field when new and old differ, which never holds against a reset baseline.
|
|
196
|
-
_config = nil;
|
|
197
|
-
_spoilerManager = nil;
|
|
198
|
-
|
|
199
|
-
_md4cFlags = [ENRMMd4cFlags propsDefaultFlags];
|
|
200
|
-
_maxFontSizeMultiplier = 0;
|
|
201
|
-
_allowTrailingMargin = NO;
|
|
202
|
-
_fontScaleObserver.allowFontScaling = YES;
|
|
203
|
-
_streamingAnimation = NO;
|
|
204
|
-
_lineBreakStrategy = NSLineBreakStrategyNone;
|
|
205
|
-
_writingDirectionMode = ENRMWritingDirectionModeFirstStrong;
|
|
206
|
-
_contextMenuItemTexts = nil;
|
|
207
|
-
_contextMenuItemIcons = nil;
|
|
208
|
-
_accessibilityLabels = nil;
|
|
209
|
-
|
|
210
|
-
// Written only once a render completes, so stale until the next one lands.
|
|
211
|
-
_renderedStyleFingerprint = 0;
|
|
212
|
-
_pendingStyleFingerprint = 0;
|
|
213
|
-
_lastElementMarginBottom = 0;
|
|
223
|
+
// A block image resolved its box height after loading (maxHeight/aspectRatio
|
|
224
|
+
// sizing). The shadow node measured — and cached — this markdown with the
|
|
225
|
+
// pre-load fallback height, so drop those entries and re-measure.
|
|
226
|
+
- (void)imageAttachmentDidResolveLayout
|
|
227
|
+
{
|
|
228
|
+
if (_renderedMarkdown.length > 0) {
|
|
229
|
+
facebook::react::MeasurementCache::shared().removeMatchingMarkdown(std::string(_renderedMarkdown.UTF8String));
|
|
230
|
+
}
|
|
214
231
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
232
|
+
if (self.bounds.size.width > 0) {
|
|
233
|
+
CGSize measured = [self measureSize:self.bounds.size.width];
|
|
234
|
+
if (needsHeightUpdate(measured, self.bounds)) {
|
|
235
|
+
[self requestHeightUpdate];
|
|
236
|
+
}
|
|
237
|
+
[self emitLinkLayoutIfNeeded];
|
|
238
|
+
}
|
|
219
239
|
}
|
|
220
240
|
|
|
221
241
|
- (instancetype)initWithFrame:(CGRect)frame
|
|
@@ -226,18 +246,25 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
226
246
|
|
|
227
247
|
self.backgroundColor = [RCTUIColor clearColor];
|
|
228
248
|
_parser = [[ENRMMarkdownParser alloc] init];
|
|
249
|
+
_md4cFlags = [EnrichedMarkdownText flagsFromProps:defaultProps->md4cFlags];
|
|
229
250
|
|
|
230
251
|
_renderCoordinator =
|
|
231
252
|
[[ENRMAsyncRenderCoordinator alloc] initWithQueueLabel:"com.swmansion.enriched.markdown.render"];
|
|
232
253
|
|
|
254
|
+
_maxFontSizeMultiplier = 0;
|
|
255
|
+
_allowTrailingMargin = NO;
|
|
233
256
|
_enableLinkPreview = YES;
|
|
234
|
-
|
|
257
|
+
_enableTaskListItemToggle = YES;
|
|
258
|
+
_forceHeightUpdateOnNextRender = NO;
|
|
259
|
+
_contextMenuHidden = NO;
|
|
260
|
+
_selectionMenuConfig = ENRMDefaultSelectionMenuConfig();
|
|
261
|
+
_lineBreakStrategy = NSLineBreakStrategyNone;
|
|
262
|
+
_writingDirectionMode = ENRMWritingDirectionModeFirstStrong;
|
|
235
263
|
_resolvedLayoutDirection =
|
|
236
264
|
[[RCTI18nUtil sharedInstance] isRTL] ? NSWritingDirectionRightToLeft : NSWritingDirectionLeftToRight;
|
|
265
|
+
_dirtyFlags = ENRMDirtyNone;
|
|
237
266
|
|
|
238
267
|
_fontScaleObserver = [[FontScaleObserver alloc] init];
|
|
239
|
-
[self resetPropDerivedState];
|
|
240
|
-
|
|
241
268
|
__weak EnrichedMarkdownText *weakSelf = self;
|
|
242
269
|
_fontScaleObserver.onChange = ^{
|
|
243
270
|
EnrichedMarkdownText *strongSelf = weakSelf;
|
|
@@ -253,11 +280,82 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
253
280
|
};
|
|
254
281
|
|
|
255
282
|
[self setupTextView];
|
|
283
|
+
[self setupSelectionReporter];
|
|
256
284
|
}
|
|
257
285
|
|
|
258
286
|
return self;
|
|
259
287
|
}
|
|
260
288
|
|
|
289
|
+
- (void)setupSelectionReporter
|
|
290
|
+
{
|
|
291
|
+
__weak EnrichedMarkdownText *weakSelf = self;
|
|
292
|
+
_selectionReporter = [[ENRMSelectionChangeReporter alloc]
|
|
293
|
+
initWithSnapshot:^NSDictionary * {
|
|
294
|
+
EnrichedMarkdownText *strongSelf = weakSelf;
|
|
295
|
+
return strongSelf ? [strongSelf selectionPayload] : ENRMInactiveSelectionPayload();
|
|
296
|
+
}
|
|
297
|
+
emit:^(NSDictionary *payload) {
|
|
298
|
+
EnrichedMarkdownText *strongSelf = weakSelf;
|
|
299
|
+
if (!strongSelf)
|
|
300
|
+
return;
|
|
301
|
+
auto emitter = std::static_pointer_cast<EnrichedMarkdownTextEventEmitter const>(strongSelf->_eventEmitter);
|
|
302
|
+
if (emitter)
|
|
303
|
+
emitter->onSelectionChange(
|
|
304
|
+
ENRMSelectionChangeEventFromPayload<EnrichedMarkdownTextEventEmitter::OnSelectionChange>(payload));
|
|
305
|
+
}];
|
|
306
|
+
#if !TARGET_OS_OSX
|
|
307
|
+
// A handle drag starting or ending is reported right away, even when the
|
|
308
|
+
// selection itself is unchanged.
|
|
309
|
+
_selectionGestures = [[ENRMSelectionGestureTracker alloc] initWithChange:^{
|
|
310
|
+
EnrichedMarkdownText *strongSelf = weakSelf;
|
|
311
|
+
if (!strongSelf)
|
|
312
|
+
return;
|
|
313
|
+
[strongSelf->_selectionGestures trackTextView:strongSelf->_textView];
|
|
314
|
+
[strongSelf->_selectionReporter forgetLastReported];
|
|
315
|
+
[strongSelf->_selectionReporter flushNow];
|
|
316
|
+
}];
|
|
317
|
+
[_selectionGestures trackTextView:_textView];
|
|
318
|
+
#endif
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/// The current selection as an `onSelectionChange` payload. Markdown and
|
|
322
|
+
/// `whole` follow the same rules as the intercepted Copy (`onCopyRequest`).
|
|
323
|
+
- (NSDictionary *)selectionPayload
|
|
324
|
+
{
|
|
325
|
+
#if !TARGET_OS_OSX
|
|
326
|
+
NSDictionary *selection = ENRMTextSelectionInTextView(_textView, self);
|
|
327
|
+
if (!selection)
|
|
328
|
+
return ENRMInactiveSelectionPayload();
|
|
329
|
+
|
|
330
|
+
NSString *text = selection[ENRMSelectionTextKey];
|
|
331
|
+
NSString *markdown = markdownForRange(_textView.attributedText, _textView.selectedRange, _cachedMarkdown);
|
|
332
|
+
NSMutableDictionary *payload = [selection mutableCopy];
|
|
333
|
+
[payload removeObjectForKey:ENRMSelectionFullKey];
|
|
334
|
+
payload[ENRMSelectionActiveKey] = @YES;
|
|
335
|
+
payload[ENRMSelectionSourceKey] = @"selection";
|
|
336
|
+
payload[ENRMSelectionMarkdownKey] = markdown.length > 0 ? markdown : text;
|
|
337
|
+
payload[ENRMSelectionWholeKey] = @([selection[ENRMSelectionFullKey] boolValue] && _cachedMarkdown.length > 0);
|
|
338
|
+
payload[ENRMSelectionAdjustingKey] = @(_selectionGestures.adjusting);
|
|
339
|
+
return payload;
|
|
340
|
+
#else
|
|
341
|
+
return ENRMInactiveSelectionPayload();
|
|
342
|
+
#endif
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
- (void)clearSelection
|
|
346
|
+
{
|
|
347
|
+
#if !TARGET_OS_OSX
|
|
348
|
+
_textView.selectedRange = NSMakeRange(0, 0);
|
|
349
|
+
[_textView resignFirstResponder];
|
|
350
|
+
#endif
|
|
351
|
+
[_selectionReporter flushNow];
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
- (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args
|
|
355
|
+
{
|
|
356
|
+
RCTEnrichedMarkdownTextHandleCommand(self, commandName, args);
|
|
357
|
+
}
|
|
358
|
+
|
|
261
359
|
- (void)setupTextView
|
|
262
360
|
{
|
|
263
361
|
#if !TARGET_OS_OSX
|
|
@@ -280,6 +378,9 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
280
378
|
if (!strongSelf) {
|
|
281
379
|
return baseMenu;
|
|
282
380
|
}
|
|
381
|
+
if (strongSelf->_contextMenuHidden) {
|
|
382
|
+
return nil;
|
|
383
|
+
}
|
|
283
384
|
NSArray<NSMenuItem *> *customItems = ENRMBuildContextMenuItems(
|
|
284
385
|
strongSelf->_contextMenuItemTexts, strongSelf->_contextMenuItemIcons, textView,
|
|
285
386
|
^(NSString *itemText, NSString *selectedText, NSUInteger selectionStart, NSUInteger selectionEnd) {
|
|
@@ -451,8 +552,13 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
451
552
|
if (forceHeightUpdate || needsHeightUpdate(measured, self.bounds)) {
|
|
452
553
|
[self requestHeightUpdate];
|
|
453
554
|
}
|
|
555
|
+
|
|
556
|
+
[self emitLinkLayoutIfNeeded];
|
|
454
557
|
}
|
|
455
558
|
|
|
559
|
+
// New text drops the selection; setting attributedText doesn't call the delegate.
|
|
560
|
+
[_selectionReporter schedule];
|
|
561
|
+
|
|
456
562
|
if (_textView.hidden) {
|
|
457
563
|
dispatch_async(dispatch_get_main_queue(), ^{ self->_textView.hidden = NO; });
|
|
458
564
|
}
|
|
@@ -471,6 +577,7 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
471
577
|
{
|
|
472
578
|
[super layoutSubviews];
|
|
473
579
|
[_spoilerManager updateIfNeeded];
|
|
580
|
+
[self emitLinkLayoutIfNeeded];
|
|
474
581
|
}
|
|
475
582
|
#endif
|
|
476
583
|
|
|
@@ -495,6 +602,11 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
495
602
|
_dirtyFlags |= ENRMDirtyRender;
|
|
496
603
|
}
|
|
497
604
|
|
|
605
|
+
if (ENRMImageRequestHeadersChanged(oldViewProps.imageRequestHeaders, newViewProps.imageRequestHeaders)) {
|
|
606
|
+
[_config setImageRequestHeaders:ENRMImageRequestHeadersFromProps(newViewProps.imageRequestHeaders)];
|
|
607
|
+
_dirtyFlags |= ENRMDirtyRender;
|
|
608
|
+
}
|
|
609
|
+
|
|
498
610
|
NSLayoutManager *layoutManager = _textView.layoutManager;
|
|
499
611
|
if ([layoutManager isKindOfClass:[TextViewLayoutManager class]]) {
|
|
500
612
|
StyleConfig *currentConfig = [layoutManager valueForKey:@"config"];
|
|
@@ -503,6 +615,14 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
503
615
|
}
|
|
504
616
|
}
|
|
505
617
|
|
|
618
|
+
if (newViewProps.emitLinkLayout != _emitLinkLayout) {
|
|
619
|
+
_emitLinkLayout = newViewProps.emitLinkLayout;
|
|
620
|
+
_lastLinkLayout = nil;
|
|
621
|
+
[self emitLinkLayoutIfNeeded];
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
_selectionReporter.enabled = newViewProps.emitSelectionChange;
|
|
625
|
+
|
|
506
626
|
if (_textView.selectable != newViewProps.selectable) {
|
|
507
627
|
_textView.selectable = newViewProps.selectable;
|
|
508
628
|
}
|
|
@@ -539,33 +659,21 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
539
659
|
_dirtyFlags |= ENRMDirtyRender;
|
|
540
660
|
}
|
|
541
661
|
|
|
542
|
-
if (newViewProps.md4cFlags.underline != oldViewProps.md4cFlags.underline
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
_md4cFlags
|
|
549
|
-
_forceHeightUpdateOnNextRender = YES;
|
|
550
|
-
_dirtyFlags |= ENRMDirtyRender;
|
|
551
|
-
}
|
|
552
|
-
if (newViewProps.md4cFlags.subscript != oldViewProps.md4cFlags.subscript) {
|
|
553
|
-
_md4cFlags.subscript = newViewProps.md4cFlags.subscript;
|
|
554
|
-
_forceHeightUpdateOnNextRender = YES;
|
|
555
|
-
_dirtyFlags |= ENRMDirtyRender;
|
|
556
|
-
}
|
|
557
|
-
if (newViewProps.md4cFlags.latexMath != oldViewProps.md4cFlags.latexMath) {
|
|
558
|
-
_md4cFlags.latexMath = newViewProps.md4cFlags.latexMath;
|
|
559
|
-
_forceHeightUpdateOnNextRender = YES;
|
|
560
|
-
_dirtyFlags |= ENRMDirtyRender;
|
|
561
|
-
}
|
|
562
|
-
if (newViewProps.md4cFlags.highlight != oldViewProps.md4cFlags.highlight) {
|
|
563
|
-
_md4cFlags.highlight = newViewProps.md4cFlags.highlight;
|
|
662
|
+
if (newViewProps.md4cFlags.underline != oldViewProps.md4cFlags.underline ||
|
|
663
|
+
newViewProps.md4cFlags.superscript != oldViewProps.md4cFlags.superscript ||
|
|
664
|
+
newViewProps.md4cFlags.subscript != oldViewProps.md4cFlags.subscript ||
|
|
665
|
+
newViewProps.md4cFlags.latexMath != oldViewProps.md4cFlags.latexMath ||
|
|
666
|
+
newViewProps.md4cFlags.highlight != oldViewProps.md4cFlags.highlight ||
|
|
667
|
+
newViewProps.md4cFlags.hardSoftBreaks != oldViewProps.md4cFlags.hardSoftBreaks) {
|
|
668
|
+
_md4cFlags = [EnrichedMarkdownText flagsFromProps:newViewProps.md4cFlags];
|
|
564
669
|
_forceHeightUpdateOnNextRender = YES;
|
|
565
670
|
_dirtyFlags |= ENRMDirtyRender;
|
|
566
671
|
}
|
|
567
672
|
|
|
568
673
|
_enableLinkPreview = newViewProps.enableLinkPreview;
|
|
674
|
+
_linkLongPressSelects = newViewProps.linkLongPressSelects;
|
|
675
|
+
_enableTaskListItemToggle = newViewProps.enableTaskListItemToggle;
|
|
676
|
+
_contextMenuHidden = newViewProps.contextMenuHidden;
|
|
569
677
|
|
|
570
678
|
if (ENRMContextMenuItemsChanged(oldViewProps.contextMenuItems, newViewProps.contextMenuItems)) {
|
|
571
679
|
_contextMenuItemTexts = ENRMContextMenuTextsFromItems(newViewProps.contextMenuItems);
|
|
@@ -573,9 +681,7 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
573
681
|
}
|
|
574
682
|
|
|
575
683
|
_selectionMenuLabels = ENRMParseSelectionMenuLabels(newViewProps.selectionMenuConfig);
|
|
576
|
-
_selectionMenuConfig =
|
|
577
|
-
ENRMBuildSelectionMenuConfig(_selectionMenuLabels, newViewProps.selectionMenuConfig.copyAsMarkdown,
|
|
578
|
-
newViewProps.selectionMenuConfig.copyImageUrl);
|
|
684
|
+
_selectionMenuConfig = ENRMBuildSelectionMenuConfig(_selectionMenuLabels, newViewProps.selectionMenuConfig);
|
|
579
685
|
|
|
580
686
|
if (ENRMAccessibilityLabelsChanged(oldViewProps.accessibilityLabels, newViewProps.accessibilityLabels)) {
|
|
581
687
|
_accessibilityLabels = [[ENRMAccessibilityLabels alloc] init];
|
|
@@ -665,26 +771,52 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
665
771
|
|
|
666
772
|
- (void)prepareForRecycle
|
|
667
773
|
{
|
|
668
|
-
|
|
774
|
+
const auto resetProps = std::make_shared<const EnrichedMarkdownTextProps>();
|
|
775
|
+
_props = resetProps;
|
|
669
776
|
[_renderCoordinator invalidate];
|
|
670
777
|
|
|
671
778
|
[_fadeAnimator cancel];
|
|
672
779
|
_fadeAnimator = nil;
|
|
673
780
|
_previousTextLength = 0;
|
|
781
|
+
_streamingAnimation = NO;
|
|
782
|
+
_forceHeightUpdateOnNextRender = NO;
|
|
674
783
|
_cachedMarkdown = nil;
|
|
675
784
|
_renderedMarkdown = nil;
|
|
785
|
+
_config = nil;
|
|
786
|
+
_md4cFlags = [EnrichedMarkdownText flagsFromProps:resetProps->md4cFlags];
|
|
787
|
+
_maxFontSizeMultiplier = 0;
|
|
788
|
+
_lastElementMarginBottom = 0;
|
|
789
|
+
_allowTrailingMargin = NO;
|
|
790
|
+
_lineBreakStrategy = NSLineBreakStrategyNone;
|
|
791
|
+
_writingDirectionMode = ENRMWritingDirectionModeFirstStrong;
|
|
792
|
+
_renderedStyleFingerprint = 0;
|
|
793
|
+
_pendingStyleFingerprint = 0;
|
|
794
|
+
_contextMenuItemTexts = nil;
|
|
795
|
+
_contextMenuItemIcons = nil;
|
|
796
|
+
_fontScaleObserver.allowFontScaling = resetProps->allowFontScaling;
|
|
797
|
+
_accessibilityLabels = nil;
|
|
676
798
|
_accessibilityElements = nil;
|
|
677
799
|
_accessibilityInfo = nil;
|
|
678
800
|
_accessibilityNeedsRebuild = NO;
|
|
679
801
|
[_spoilerManager removeAllOverlays];
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
802
|
+
_spoilerManager = nil;
|
|
803
|
+
_emitLinkLayout = NO;
|
|
804
|
+
_lastLinkLayout = nil;
|
|
805
|
+
_selectionReporter.enabled = NO;
|
|
806
|
+
#if !TARGET_OS_OSX
|
|
807
|
+
[_selectionGestures reset];
|
|
808
|
+
#endif
|
|
683
809
|
if (_textView != nil) {
|
|
684
810
|
ENRMSetAttributedText(_textView, [[NSAttributedString alloc] initWithString:@""]);
|
|
685
811
|
_textView.hidden = YES;
|
|
686
812
|
}
|
|
687
813
|
|
|
814
|
+
// Ported from the fork's resetPropDerivedState: upstream's prepareForRecycle covers every
|
|
815
|
+
// other prop-derived ivar but leaves these two, so a recycled view keeps the previous
|
|
816
|
+
// consumer's height-update counter and a dangling shadow-node state handle.
|
|
817
|
+
_heightUpdateCounter = 0;
|
|
818
|
+
_state = nullptr;
|
|
819
|
+
|
|
688
820
|
[super prepareForRecycle];
|
|
689
821
|
}
|
|
690
822
|
|
|
@@ -719,6 +851,25 @@ Class<RCTComponentViewProtocol> EnrichedMarkdownTextCls(void)
|
|
|
719
851
|
emitter->onLinkLongPress({.url = std::string(url.UTF8String)});
|
|
720
852
|
}
|
|
721
853
|
|
|
854
|
+
/// Reports link rects to JS (for `renderLinkDecoration`). Called after every
|
|
855
|
+
/// render and layout change; deduplicated so an unchanged layout — the common
|
|
856
|
+
/// case during streaming — sends nothing.
|
|
857
|
+
- (void)emitLinkLayoutIfNeeded
|
|
858
|
+
{
|
|
859
|
+
if (!_emitLinkLayout || _renderedMarkdown == nil || self.bounds.size.width <= 0)
|
|
860
|
+
return;
|
|
861
|
+
|
|
862
|
+
auto emitter = std::static_pointer_cast<EnrichedMarkdownTextEventEmitter const>(_eventEmitter);
|
|
863
|
+
if (!emitter)
|
|
864
|
+
return;
|
|
865
|
+
|
|
866
|
+
NSArray<NSDictionary *> *fragments = ENRMCollectLinkLayoutFragments(_textView, CGPointZero, 0, NULL);
|
|
867
|
+
if (_lastLinkLayout != nil && [fragments isEqualToArray:_lastLinkLayout])
|
|
868
|
+
return;
|
|
869
|
+
_lastLinkLayout = fragments;
|
|
870
|
+
emitter->onLinkLayout(ENRMLinkLayoutEventFromFragments<EnrichedMarkdownTextEventEmitter::OnLinkLayout>(fragments));
|
|
871
|
+
}
|
|
872
|
+
|
|
722
873
|
- (void)emitTaskListItemPress:(NSInteger)index checked:(BOOL)checked text:(NSString *)text
|
|
723
874
|
{
|
|
724
875
|
auto emitter = std::static_pointer_cast<EnrichedMarkdownTextEventEmitter const>(_eventEmitter);
|
|
@@ -726,6 +877,18 @@ Class<RCTComponentViewProtocol> EnrichedMarkdownTextCls(void)
|
|
|
726
877
|
emitter->onTaskListItemPress({.index = (int)index, .checked = checked, .text = std::string(text.UTF8String ?: "")});
|
|
727
878
|
}
|
|
728
879
|
|
|
880
|
+
- (void)emitCopyRequest:(NSString *)source markdown:(NSString *)markdown text:(NSString *)text whole:(BOOL)whole
|
|
881
|
+
{
|
|
882
|
+
auto emitter = std::static_pointer_cast<EnrichedMarkdownTextEventEmitter const>(_eventEmitter);
|
|
883
|
+
if (emitter)
|
|
884
|
+
emitter->onCopyRequest({
|
|
885
|
+
.source = std::string(source.UTF8String),
|
|
886
|
+
.markdown = std::string(markdown.UTF8String ?: ""),
|
|
887
|
+
.text = std::string(text.UTF8String ?: ""),
|
|
888
|
+
.whole = (bool)whole,
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
|
|
729
892
|
- (void)emitContextMenuItemPress:(NSString *)itemText
|
|
730
893
|
selectedText:(NSString *)selectedText
|
|
731
894
|
selectionStart:(NSUInteger)selectionStart
|
|
@@ -745,7 +908,8 @@ Class<RCTComponentViewProtocol> EnrichedMarkdownTextCls(void)
|
|
|
745
908
|
{
|
|
746
909
|
ENRMPlatformTextView *textView = (ENRMPlatformTextView *)recognizer.view;
|
|
747
910
|
|
|
748
|
-
if (
|
|
911
|
+
if (_enableTaskListItemToggle &&
|
|
912
|
+
handleTaskListTapWithSharedLogic(
|
|
749
913
|
textView, recognizer, &self->_cachedMarkdown, self->_config,
|
|
750
914
|
^(NSInteger index, BOOL checked, NSString *itemText) {
|
|
751
915
|
[self emitTaskListItemPress:index checked:checked text:itemText];
|
|
@@ -764,6 +928,31 @@ Class<RCTComponentViewProtocol> EnrichedMarkdownTextCls(void)
|
|
|
764
928
|
#pragma mark - UITextViewDelegate (Link Interaction)
|
|
765
929
|
|
|
766
930
|
#if !TARGET_OS_OSX
|
|
931
|
+
// Attachments other than images (inline math) are text, not items: without
|
|
932
|
+
// this a long press on one in an unfocused text view starts UIKit's text item
|
|
933
|
+
// interaction, which presents nothing and leaves the view unable to select.
|
|
934
|
+
- (BOOL)textView:(UITextView *)textView
|
|
935
|
+
shouldInteractWithTextAttachment:(NSTextAttachment *)textAttachment
|
|
936
|
+
inRange:(NSRange)characterRange
|
|
937
|
+
interaction:(UITextItemInteraction)interaction
|
|
938
|
+
{
|
|
939
|
+
if ([textAttachment isKindOfClass:[ENRMImageAttachment class]]) {
|
|
940
|
+
return YES;
|
|
941
|
+
}
|
|
942
|
+
// A long press selects the attachment like a word, as it does once the view is focused.
|
|
943
|
+
if (interaction == UITextItemInteractionPresentActions) {
|
|
944
|
+
__weak UITextView *weakTextView = textView;
|
|
945
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
946
|
+
UITextView *strongTextView = weakTextView;
|
|
947
|
+
if (!strongTextView || NSMaxRange(characterRange) > strongTextView.attributedText.length) {
|
|
948
|
+
return;
|
|
949
|
+
}
|
|
950
|
+
ENRMSelectRangeAndPresentEditMenu(strongTextView, characterRange);
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
return NO;
|
|
954
|
+
}
|
|
955
|
+
|
|
767
956
|
- (BOOL)textView:(ENRMPlatformTextView *)textView
|
|
768
957
|
shouldInteractWithURL:(NSURL *)URL
|
|
769
958
|
inRange:(NSRange)characterRange
|
|
@@ -775,6 +964,18 @@ Class<RCTComponentViewProtocol> EnrichedMarkdownTextCls(void)
|
|
|
775
964
|
|
|
776
965
|
NSString *urlString = linkURLAtRange(textView, characterRange);
|
|
777
966
|
|
|
967
|
+
if (urlString && _linkLongPressSelects) {
|
|
968
|
+
__weak UITextView *weakTextView = textView;
|
|
969
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
970
|
+
UITextView *strongTextView = weakTextView;
|
|
971
|
+
if (!strongTextView || NSMaxRange(characterRange) > strongTextView.attributedText.length) {
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
974
|
+
ENRMSelectRangeAndPresentEditMenu(strongTextView, characterRange);
|
|
975
|
+
});
|
|
976
|
+
return NO;
|
|
977
|
+
}
|
|
978
|
+
|
|
778
979
|
if (!urlString || _enableLinkPreview) {
|
|
779
980
|
return YES;
|
|
780
981
|
}
|
|
@@ -783,6 +984,15 @@ Class<RCTComponentViewProtocol> EnrichedMarkdownTextCls(void)
|
|
|
783
984
|
return NO;
|
|
784
985
|
}
|
|
785
986
|
|
|
987
|
+
#pragma mark - UITextViewDelegate (Selection)
|
|
988
|
+
|
|
989
|
+
- (void)textViewDidChangeSelection:(UITextView *)textView
|
|
990
|
+
{
|
|
991
|
+
[_selectionGestures trackTextView:textView];
|
|
992
|
+
ENRMDismissSelectionEditMenuIfMoved(textView);
|
|
993
|
+
[_selectionReporter selectionChanged:textView.selectedRange.length > 0];
|
|
994
|
+
}
|
|
995
|
+
|
|
786
996
|
#pragma mark - UITextViewDelegate (Edit Menu)
|
|
787
997
|
|
|
788
998
|
// TODO: Remove API_AVAILABLE(ios(16.0)) guard when the minimum iOS deployment target in RN is bumped to 16.
|
|
@@ -790,6 +1000,12 @@ Class<RCTComponentViewProtocol> EnrichedMarkdownTextCls(void)
|
|
|
790
1000
|
editMenuForTextInRange:(NSRange)range
|
|
791
1001
|
suggestedActions:(NSArray<UIMenuElement *> *)suggestedActions API_AVAILABLE(ios(16.0))
|
|
792
1002
|
{
|
|
1003
|
+
// An empty menu presents nothing; nil would make UIKit show its default menu
|
|
1004
|
+
// (the selection and handles stay either way).
|
|
1005
|
+
if (_contextMenuHidden) {
|
|
1006
|
+
return [UIMenu menuWithChildren:@[]];
|
|
1007
|
+
}
|
|
1008
|
+
|
|
793
1009
|
__weak EnrichedMarkdownText *weakSelf = self;
|
|
794
1010
|
ENRMContextMenuPressHandler handler =
|
|
795
1011
|
^(NSString *itemText, NSString *selectedText, NSUInteger selectionStart, NSUInteger selectionEnd) {
|
|
@@ -803,8 +1019,18 @@ Class<RCTComponentViewProtocol> EnrichedMarkdownTextCls(void)
|
|
|
803
1019
|
NSMutableArray<UIAction *> *customActions =
|
|
804
1020
|
ENRMBuildContextMenuActions(_contextMenuItemTexts, _contextMenuItemIcons, textView, range, handler);
|
|
805
1021
|
|
|
1022
|
+
// A full selection already carries the cached (original) markdown.
|
|
1023
|
+
ENRMCopyRequestHandler onCopyRequest = ^(NSString *markdown, NSString *text, BOOL fullSelection) {
|
|
1024
|
+
EnrichedMarkdownText *strongSelf = weakSelf;
|
|
1025
|
+
if (strongSelf)
|
|
1026
|
+
[strongSelf emitCopyRequest:@"selection"
|
|
1027
|
+
markdown:markdown
|
|
1028
|
+
text:text
|
|
1029
|
+
whole:fullSelection && strongSelf->_cachedMarkdown.length > 0];
|
|
1030
|
+
};
|
|
1031
|
+
|
|
806
1032
|
return buildEditMenuForSelection(textView.attributedText, range, _cachedMarkdown, _config, suggestedActions,
|
|
807
|
-
customActions, _selectionMenuConfig);
|
|
1033
|
+
customActions, _selectionMenuConfig, onCopyRequest);
|
|
808
1034
|
}
|
|
809
1035
|
#endif
|
|
810
1036
|
|
|
@@ -5,6 +5,15 @@
|
|
|
5
5
|
|
|
6
6
|
NS_ASSUME_NONNULL_BEGIN
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Adopted by component views that host markdown text. Notified when a block
|
|
10
|
+
* image resolves its box height after loading (maxHeight/aspectRatio sizing),
|
|
11
|
+
* so the view can drop stale cached measurements and request a height update.
|
|
12
|
+
*/
|
|
13
|
+
@protocol ENRMImageLayoutObserver
|
|
14
|
+
- (void)imageAttachmentDidResolveLayout;
|
|
15
|
+
@end
|
|
16
|
+
|
|
8
17
|
/**
|
|
9
18
|
* Custom NSTextAttachment for rendering markdown images.
|
|
10
19
|
* Images are loaded asynchronously and scaled dynamically based on text container width.
|