react-native-enriched-markdown-scaffold 0.7.4-scaffold.9 → 1.0.2-scaffold.2
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 +186 -1
- package/android/consumer-rules.pro +1 -1
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +9 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +3 -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 +9 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +3 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +35 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +886 -23
- 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 +189 -13
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +50 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +48 -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 +42 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +82 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/events/CopyPressEvent.kt +24 -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 +901 -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 +101 -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/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 +30 -27
- 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 +27 -3
- 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/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/ListStyle.kt +4 -1
- 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 +37 -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 +20 -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/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/LinkLongPressMovementMethod.kt +58 -27
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +49 -15
- package/android/src/main/java/com/swmansion/enriched/markdown/views/BlockMenuOptions.kt +45 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +396 -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 +36 -9
- 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 +7 -2
- package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +1 -1
- package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +6 -4
- 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 +234 -12
- package/docs/BREAKING_CHANGES.md +129 -0
- package/docs/CODE_HIGHLIGHT.md +133 -0
- package/docs/COPY_OPTIONS.md +47 -3
- package/docs/ELEMENTS_STRUCTURE.md +52 -4
- package/docs/IMAGE_CACHING.md +30 -0
- package/docs/INPUT.md +108 -11
- package/docs/LATEX_MATH.md +87 -45
- package/docs/MACOS.md +1 -1
- package/docs/MARKDOWN_STREAMING.md +27 -1
- package/docs/NATIVE_ASSETS.md +127 -0
- package/docs/RTL.md +1 -1
- package/docs/STYLES.md +46 -6
- package/docs/TESTING.md +112 -0
- package/docs/TEXT.md +16 -6
- package/docs/WEB.md +3 -1
- package/ios/EnrichedMarkdown.h +7 -0
- package/ios/EnrichedMarkdown.mm +284 -75
- package/ios/EnrichedMarkdownText.h +7 -0
- package/ios/EnrichedMarkdownText.mm +101 -73
- package/ios/attachments/ENRMImageAttachment.h +9 -0
- package/ios/attachments/ENRMImageAttachment.m +143 -40
- package/ios/attachments/ENRMMathInlineAttachment.h +2 -0
- package/ios/attachments/ENRMMathInlineAttachment.m +48 -81
- package/ios/attachments/ENRMMathInlineAttachmentShared.h +2 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +35 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +886 -23
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +131 -0
- 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 +33 -7
- 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 +4 -1
- 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 +5 -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 +3 -1
- 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 +22 -0
- package/ios/styles/StyleConfig.mm +132 -0
- package/ios/utils/BlockquoteBorder.h +6 -0
- package/ios/utils/BlockquoteBorder.m +249 -52
- package/ios/utils/CodeBlockBackground.m +16 -2
- package/ios/utils/ENRMAtomicSize.h +65 -0
- package/ios/utils/ENRMBlockMenu.h +57 -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/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/ENRMTextViewSetup.h +35 -17
- package/ios/utils/EditMenuUtils.h +22 -5
- package/ios/utils/EditMenuUtils.m +53 -9
- 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/ParagraphStyleUtils.h +5 -0
- package/ios/utils/ParagraphStyleUtils.m +77 -17
- 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 +63 -0
- package/ios/utils/TaskListTapUtils.m +24 -0
- package/ios/views/ENRMCodeBlockContainerView.h +53 -0
- package/ios/views/ENRMCodeBlockContainerView.m +559 -0
- package/ios/views/ENRMMathContainerView.h +16 -0
- package/ios/views/ENRMMathContainerView.m +74 -19
- package/ios/views/TableContainerView.h +22 -0
- package/ios/views/TableContainerView.m +261 -175
- package/jest.d.ts +1 -0
- package/jest.js +5 -0
- package/lib/module/EnrichedMarkdownNativeComponent.ts +73 -0
- 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 +74 -0
- 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 +191 -0
- package/lib/module/jest/index.js.map +1 -0
- package/lib/module/native/EnrichedMarkdownText.js +37 -5
- package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
- package/lib/module/normalizeMarkdownStyle.js +81 -19
- package/lib/module/normalizeMarkdownStyle.js.map +1 -1
- package/lib/module/normalizeMarkdownStyle.web.js +56 -18
- 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 +9 -5
- 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 +6 -0
- 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 +83 -6
- package/lib/module/web/styles.js.map +1 -1
- package/lib/module/web/utils.js +1 -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 +66 -0
- 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 +66 -0
- 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 +2 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/index.web.d.ts +1 -1
- 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 +3 -3
- 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 +72 -0
- package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +27 -0
- package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownTextProps.d.ts +104 -9
- package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownTextProps.web.d.ts +19 -0
- package/lib/typescript/src/types/MarkdownTextProps.web.d.ts.map +1 -1
- package/lib/typescript/src/types/events.d.ts +19 -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 +6 -2
- package/lib/typescript/src/web/types.d.ts.map +1 -1
- 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 +73 -0
- package/src/EnrichedMarkdownTextInput.tsx +159 -8
- package/src/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
- package/src/EnrichedMarkdownTextNativeComponent.ts +74 -0
- package/src/headingDefaults.ts +21 -0
- package/src/index.tsx +9 -0
- package/src/index.web.tsx +1 -0
- package/src/jest/index.tsx +215 -0
- package/src/native/EnrichedMarkdownText.tsx +53 -2
- package/src/normalizeMarkdownStyle.ts +102 -16
- package/src/normalizeMarkdownStyle.web.ts +63 -15
- package/src/normalizeMarkdownTextInputStyle.ts +110 -35
- package/src/normalizeMenuItem.ts +1 -1
- package/src/types/MarkdownStyle.ts +74 -0
- package/src/types/MarkdownStyleInternal.ts +39 -0
- package/src/types/MarkdownTextProps.ts +101 -9
- package/src/types/MarkdownTextProps.web.ts +19 -0
- package/src/types/events.ts +21 -0
- package/src/utils/textInputState.ts +35 -0
- package/src/web/EnrichedMarkdownText.tsx +16 -2
- package/src/web/parseMarkdown.ts +6 -2
- package/src/web/renderers/InlineRenderers.tsx +5 -0
- package/src/web/renderers/ListRenderers.tsx +14 -2
- package/src/web/renderers/index.tsx +6 -2
- package/src/web/styles.ts +89 -5
- package/src/web/types.ts +6 -1
- package/src/web/utils.ts +1 -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
|
@@ -8,6 +8,8 @@ import android.text.style.StrikethroughSpan
|
|
|
8
8
|
import android.widget.TextView
|
|
9
9
|
import com.swmansion.enriched.markdown.renderer.SpanStyleCache
|
|
10
10
|
import com.swmansion.enriched.markdown.spans.BaseListSpan
|
|
11
|
+
import com.swmansion.enriched.markdown.spans.CodeBlockSpan
|
|
12
|
+
import com.swmansion.enriched.markdown.spans.ListMarkerAnchorSpan
|
|
11
13
|
import com.swmansion.enriched.markdown.spans.TaskListSpan
|
|
12
14
|
import com.swmansion.enriched.markdown.styles.StyleConfig
|
|
13
15
|
import com.swmansion.enriched.markdown.utils.text.span.SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE
|
|
@@ -101,51 +103,69 @@ object TaskListTapUtils {
|
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
val spannable = SpannableStringBuilder(text)
|
|
104
|
-
val
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
val targetSpans =
|
|
107
|
+
spannable
|
|
108
|
+
.getSpans(0, spannable.length, TaskListSpan::class.java)
|
|
109
|
+
.filter { it.taskIndex == targetIndex }
|
|
110
|
+
if (targetSpans.isEmpty()) {
|
|
108
111
|
return false
|
|
109
112
|
}
|
|
110
113
|
|
|
111
|
-
if (
|
|
114
|
+
if (targetSpans.all { it.isChecked == newChecked }) {
|
|
112
115
|
return true
|
|
113
116
|
}
|
|
114
117
|
|
|
115
|
-
val
|
|
116
|
-
val
|
|
117
|
-
val
|
|
118
|
+
val itemDepth = targetSpans.first().depth
|
|
119
|
+
val spanStart = targetSpans.minOf { spannable.getSpanStart(it) }
|
|
120
|
+
val spanEnd = targetSpans.maxOf { spannable.getSpanEnd(it) }
|
|
118
121
|
|
|
119
122
|
val styleCache = SpanStyleCache(styleConfig)
|
|
120
|
-
|
|
123
|
+
|
|
124
|
+
fun toggledCopy(old: TaskListSpan): TaskListSpan =
|
|
121
125
|
TaskListSpan(
|
|
122
126
|
taskStyle = styleConfig.taskListStyle,
|
|
123
127
|
listStyle = styleConfig.listStyle,
|
|
124
|
-
depth =
|
|
128
|
+
depth = old.depth,
|
|
125
129
|
context = textView.context,
|
|
126
130
|
styleCache = styleCache,
|
|
127
131
|
taskIndex = targetIndex,
|
|
128
132
|
isChecked = newChecked,
|
|
133
|
+
drawsMarker = old.drawsMarker,
|
|
129
134
|
)
|
|
130
135
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return false
|
|
136
|
+
// Replace every segment of the item — spans are split around code blocks
|
|
137
|
+
for (old in targetSpans) {
|
|
138
|
+
val start = spannable.getSpanStart(old)
|
|
139
|
+
val end = spannable.getSpanEnd(old)
|
|
140
|
+
spannable.removeSpan(old)
|
|
141
|
+
spannable.setSpan(toggledCopy(old), start, end, SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE)
|
|
138
142
|
}
|
|
139
143
|
|
|
144
|
+
// The marker may be drawn by an anchor span wrapping an unattached copy
|
|
145
|
+
spannable
|
|
146
|
+
.getSpans(0, spannable.length, ListMarkerAnchorSpan::class.java)
|
|
147
|
+
.filter { (it.marker as? TaskListSpan)?.taskIndex == targetIndex }
|
|
148
|
+
.forEach { old ->
|
|
149
|
+
val start = spannable.getSpanStart(old)
|
|
150
|
+
val end = spannable.getSpanEnd(old)
|
|
151
|
+
spannable.removeSpan(old)
|
|
152
|
+
spannable.setSpan(
|
|
153
|
+
ListMarkerAnchorSpan(toggledCopy(old.marker as TaskListSpan)),
|
|
154
|
+
start,
|
|
155
|
+
end,
|
|
156
|
+
SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE,
|
|
157
|
+
)
|
|
158
|
+
}
|
|
159
|
+
|
|
140
160
|
val taskStyle = styleConfig.taskListStyle
|
|
141
161
|
val checkedTextColor = taskStyle.checkedTextColor
|
|
142
162
|
val strikethrough = taskStyle.checkedStrikethrough
|
|
143
163
|
|
|
144
164
|
val excludedRanges =
|
|
145
|
-
|
|
146
|
-
.getSpans(spanStart, spanEnd, BaseListSpan::class.java)
|
|
147
|
-
|
|
148
|
-
|
|
165
|
+
(
|
|
166
|
+
spannable.getSpans(spanStart, spanEnd, BaseListSpan::class.java).filter { it.depth > itemDepth } +
|
|
167
|
+
spannable.getSpans(spanStart, spanEnd, CodeBlockSpan::class.java).toList()
|
|
168
|
+
).map { spannable.getSpanStart(it) to spannable.getSpanEnd(it) }
|
|
149
169
|
.sortedBy { it.first }
|
|
150
170
|
|
|
151
171
|
applyDecorationsToRanges(
|
package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package com.swmansion.enriched.markdown.utils.text.span
|
|
2
2
|
|
|
3
3
|
import android.text.SpannableStringBuilder
|
|
4
|
+
import com.swmansion.enriched.markdown.spans.CodeBlockSpan
|
|
4
5
|
import com.swmansion.enriched.markdown.spans.ImageSpan
|
|
5
6
|
import com.swmansion.enriched.markdown.spans.LineHeightSpan
|
|
6
7
|
import com.swmansion.enriched.markdown.spans.MarginBottomSpan
|
|
@@ -11,9 +12,9 @@ fun createLineHeightSpan(lineHeight: Float): AndroidLineHeightSpan = LineHeightS
|
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Applies [LineHeightSpan] to [start]..[end] but skips ranges occupied by
|
|
14
|
-
* block [ImageSpan]s (and their trailing '\n')
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* block [ImageSpan]s (and their trailing '\n') and by [CodeBlockSpan]s —
|
|
16
|
+
* both of these apply their own font-metric adjustments that a fixed
|
|
17
|
+
* line height would override.
|
|
17
18
|
*/
|
|
18
19
|
fun applyLineHeightSkippingImages(
|
|
19
20
|
builder: SpannableStringBuilder,
|
|
@@ -26,19 +27,25 @@ fun applyLineHeightSkippingImages(
|
|
|
26
27
|
.getSpans(start, end, ImageSpan::class.java)
|
|
27
28
|
.filter { !it.isInline }
|
|
28
29
|
.map { builder.getSpanStart(it) to builder.getSpanEnd(it) }
|
|
29
|
-
|
|
30
|
+
|
|
31
|
+
val codeBlockRanges =
|
|
32
|
+
builder
|
|
33
|
+
.getSpans(start, end, CodeBlockSpan::class.java)
|
|
34
|
+
.map { builder.getSpanStart(it) to builder.getSpanEnd(it) }
|
|
35
|
+
|
|
36
|
+
val excludedRanges = (blockImageRanges + codeBlockRanges).sortedBy { it.first }
|
|
30
37
|
|
|
31
38
|
var pos = start
|
|
32
|
-
for ((
|
|
33
|
-
if (pos <
|
|
39
|
+
for ((exStart, exEnd) in excludedRanges) {
|
|
40
|
+
if (pos < exStart) {
|
|
34
41
|
builder.setSpan(
|
|
35
42
|
createLineHeightSpan(lineHeight),
|
|
36
43
|
pos,
|
|
37
|
-
|
|
44
|
+
exStart,
|
|
38
45
|
SPAN_FLAGS_EXCLUSIVE_EXCLUSIVE,
|
|
39
46
|
)
|
|
40
47
|
}
|
|
41
|
-
val skipEnd = if (
|
|
48
|
+
val skipEnd = if (exEnd < end && builder[exEnd] == '\n') exEnd + 1 else exEnd
|
|
42
49
|
pos = maxOf(pos, skipEnd)
|
|
43
50
|
}
|
|
44
51
|
if (pos < end) {
|
|
@@ -2,9 +2,8 @@ package com.swmansion.enriched.markdown.utils.text.view
|
|
|
2
2
|
|
|
3
3
|
import android.os.Handler
|
|
4
4
|
import android.os.Looper
|
|
5
|
-
import android.text.Selection
|
|
6
5
|
import android.text.Spannable
|
|
7
|
-
import android.text.method.
|
|
6
|
+
import android.text.method.ArrowKeyMovementMethod
|
|
8
7
|
import android.view.MotionEvent
|
|
9
8
|
import android.view.ViewConfiguration
|
|
10
9
|
import android.widget.TextView
|
|
@@ -13,15 +12,26 @@ import com.swmansion.enriched.markdown.spans.SpoilerSpan
|
|
|
13
12
|
import com.swmansion.enriched.markdown.spoiler.SpoilerCapable
|
|
14
13
|
import kotlin.math.abs
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Movement method that adds link tap / long-press and spoiler tap handling on
|
|
17
|
+
* top of [ArrowKeyMovementMethod], the method [setTextIsSelectable] installs.
|
|
18
|
+
*
|
|
19
|
+
* Must never mutate the buffer's Selection spans — the platform Editor
|
|
20
|
+
* manages them during long-press gestures, and removing or overwriting
|
|
21
|
+
* them mid-gesture crashes on some OEM skins.
|
|
22
|
+
* See: https://github.com/software-mansion/enriched-markdown/issues/580
|
|
23
|
+
*/
|
|
24
|
+
class LinkLongPressMovementMethod : ArrowKeyMovementMethod() {
|
|
17
25
|
private val handler = Handler(Looper.getMainLooper())
|
|
18
26
|
private var longPressRunnable: Runnable? = null
|
|
19
27
|
|
|
20
28
|
private var startX = 0f
|
|
21
29
|
private var startY = 0f
|
|
30
|
+
private var pressedLink: LinkSpan? = null
|
|
22
31
|
|
|
23
32
|
var isLinkTouchActive: Boolean = false
|
|
24
33
|
private set
|
|
34
|
+
private var isTouchWithinTextBounds: Boolean = true
|
|
25
35
|
|
|
26
36
|
override fun onTouchEvent(
|
|
27
37
|
widget: TextView,
|
|
@@ -33,9 +43,10 @@ class LinkLongPressMovementMethod : LinkMovementMethod() {
|
|
|
33
43
|
startX = event.x
|
|
34
44
|
startY = event.y
|
|
35
45
|
|
|
36
|
-
|
|
37
|
-
isLinkTouchActive =
|
|
38
|
-
|
|
46
|
+
pressedLink = findLinkSpan(widget, buffer, event)
|
|
47
|
+
isLinkTouchActive = pressedLink != null
|
|
48
|
+
isTouchWithinTextBounds = charOffsetAt(widget, event) != null
|
|
49
|
+
pressedLink?.let { scheduleLongPress(widget, it) }
|
|
39
50
|
}
|
|
40
51
|
|
|
41
52
|
MotionEvent.ACTION_MOVE -> {
|
|
@@ -45,17 +56,25 @@ class LinkLongPressMovementMethod : LinkMovementMethod() {
|
|
|
45
56
|
) {
|
|
46
57
|
cancelLongPress()
|
|
47
58
|
isLinkTouchActive = false
|
|
59
|
+
pressedLink = null
|
|
48
60
|
}
|
|
49
61
|
}
|
|
50
62
|
|
|
51
63
|
MotionEvent.ACTION_UP -> {
|
|
52
64
|
cancelLongPress()
|
|
65
|
+
val tappedLink = pressedLink
|
|
53
66
|
isLinkTouchActive = false
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
67
|
+
pressedLink = null
|
|
68
|
+
|
|
57
69
|
if (handleSpoilerTap(widget, buffer, event)) {
|
|
58
|
-
|
|
70
|
+
return true
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// LinkSpan.onClick itself swallows the click that follows a completed
|
|
74
|
+
// long-press (and resets its internal flag), so it is always invoked
|
|
75
|
+
// for a tap that started and ended on the same link.
|
|
76
|
+
if (tappedLink != null && findLinkSpan(widget, buffer, event) === tappedLink) {
|
|
77
|
+
tappedLink.onClick(widget)
|
|
59
78
|
return true
|
|
60
79
|
}
|
|
61
80
|
}
|
|
@@ -63,22 +82,19 @@ class LinkLongPressMovementMethod : LinkMovementMethod() {
|
|
|
63
82
|
MotionEvent.ACTION_CANCEL -> {
|
|
64
83
|
cancelLongPress()
|
|
65
84
|
isLinkTouchActive = false
|
|
66
|
-
|
|
67
|
-
Selection.removeSelection(buffer)
|
|
68
|
-
}
|
|
85
|
+
pressedLink = null
|
|
69
86
|
}
|
|
70
87
|
}
|
|
71
88
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
//
|
|
75
|
-
//
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
Selection.removeSelection(buffer)
|
|
89
|
+
// getOffsetForHorizontal snaps to the nearest character, so without this
|
|
90
|
+
// guard taps in empty space past the end of a line would still be treated
|
|
91
|
+
// as text touches. Let them fall through to the parent (e.g. RNGH
|
|
92
|
+
// Pressable) instead.
|
|
93
|
+
if (!isTouchWithinTextBounds) {
|
|
94
|
+
return false
|
|
79
95
|
}
|
|
80
96
|
|
|
81
|
-
return
|
|
97
|
+
return super.onTouchEvent(widget, buffer, event)
|
|
82
98
|
}
|
|
83
99
|
|
|
84
100
|
private fun scheduleLongPress(
|
|
@@ -89,9 +105,6 @@ class LinkLongPressMovementMethod : LinkMovementMethod() {
|
|
|
89
105
|
|
|
90
106
|
longPressRunnable =
|
|
91
107
|
Runnable {
|
|
92
|
-
if (widget.hasSelection()) {
|
|
93
|
-
Selection.removeSelection(widget.text as Spannable)
|
|
94
|
-
}
|
|
95
108
|
// Execute the long click logic on the span
|
|
96
109
|
if (span.onLongClick(widget)) {
|
|
97
110
|
// If consumed, cancel the system's own long-press logic (like context menus)
|
|
@@ -112,10 +125,28 @@ class LinkLongPressMovementMethod : LinkMovementMethod() {
|
|
|
112
125
|
widget: TextView,
|
|
113
126
|
event: MotionEvent,
|
|
114
127
|
): Int? {
|
|
115
|
-
val x = event.x
|
|
116
|
-
val y = event.y
|
|
128
|
+
val x = event.x - widget.totalPaddingLeft + widget.scrollX
|
|
129
|
+
val y = event.y - widget.totalPaddingTop + widget.scrollY
|
|
117
130
|
val layout = widget.layout ?: return null
|
|
118
|
-
|
|
131
|
+
|
|
132
|
+
// getLineForVertical clamps to the first/last line for out-of-range
|
|
133
|
+
// values, so taps in vertical padding would silently map to a real
|
|
134
|
+
// line. Reject them before proceeding.
|
|
135
|
+
if (y < 0f || y > layout.height) {
|
|
136
|
+
return null
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
val line = layout.getLineForVertical(y.toInt())
|
|
140
|
+
|
|
141
|
+
// getOffsetForHorizontal snaps to the nearest character even when the
|
|
142
|
+
// tap is outside the actual text content (e.g. empty space after the
|
|
143
|
+
// last word on a line). Guard against that by checking the tap falls
|
|
144
|
+
// within the line's text bounds.
|
|
145
|
+
if (x < layout.getLineLeft(line) || x > layout.getLineRight(line)) {
|
|
146
|
+
return null
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return layout.getOffsetForHorizontal(line, x)
|
|
119
150
|
}
|
|
120
151
|
|
|
121
152
|
private fun findLinkSpan(
|
package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt
CHANGED
|
@@ -32,6 +32,12 @@ data class SelectionMenuConfig(
|
|
|
32
32
|
// Plural templates indexed by image count (0..100). Empty when no pluralLabels
|
|
33
33
|
// are set; counts > 100 use copyImageUrlsLabel (the "other" form).
|
|
34
34
|
val copyImageUrlPluralTemplates: List<String> = emptyList(),
|
|
35
|
+
val copyEnabled: Boolean = true,
|
|
36
|
+
// Copy writes Markdown (plain text) instead of plain + HTML / raw block content.
|
|
37
|
+
val copyFormatMarkdown: Boolean = false,
|
|
38
|
+
// Drop every system-provided item (Select all, Share, text assist, PROCESS_TEXT…).
|
|
39
|
+
val systemItemsNone: Boolean = false,
|
|
40
|
+
val codeBlockCopyButton: Boolean = true,
|
|
35
41
|
)
|
|
36
42
|
|
|
37
43
|
/**
|
|
@@ -57,6 +63,10 @@ fun createSelectionActionModeCallback(
|
|
|
57
63
|
textView: TextView,
|
|
58
64
|
getCustomItemTexts: () -> List<String> = { emptyList() },
|
|
59
65
|
getSelectionMenuConfig: () -> SelectionMenuConfig = { SelectionMenuConfig() },
|
|
66
|
+
isContextMenuHidden: () -> Boolean = { false },
|
|
67
|
+
// Lets the owning view hold the live ActionMode so it can invalidate() the
|
|
68
|
+
// toolbar when a prop changes while the menu is already on screen.
|
|
69
|
+
onActionModeChanged: (mode: ActionMode?) -> Unit = {},
|
|
60
70
|
onCustomItemPress: (itemText: String, selectedText: String, selectionStart: Int, selectionEnd: Int) -> Unit =
|
|
61
71
|
{ _, _, _, _ -> },
|
|
62
72
|
): ActionMode.Callback =
|
|
@@ -64,7 +74,10 @@ fun createSelectionActionModeCallback(
|
|
|
64
74
|
override fun onCreateActionMode(
|
|
65
75
|
mode: ActionMode?,
|
|
66
76
|
menu: Menu?,
|
|
67
|
-
): Boolean
|
|
77
|
+
): Boolean {
|
|
78
|
+
onActionModeChanged(mode)
|
|
79
|
+
return true
|
|
80
|
+
}
|
|
68
81
|
|
|
69
82
|
override fun onPrepareActionMode(
|
|
70
83
|
mode: ActionMode?,
|
|
@@ -72,24 +85,39 @@ fun createSelectionActionModeCallback(
|
|
|
72
85
|
): Boolean {
|
|
73
86
|
if (menu == null) return false
|
|
74
87
|
|
|
88
|
+
// Keep the ActionMode alive (selection handles and highlighting stay
|
|
89
|
+
// usable, which is what TalkBack relies on) but ship an empty menu so
|
|
90
|
+
// the floating toolbar has nothing to show.
|
|
91
|
+
if (isContextMenuHidden()) {
|
|
92
|
+
menu.clear()
|
|
93
|
+
return true
|
|
94
|
+
}
|
|
95
|
+
|
|
75
96
|
menu.removeItem(MENU_ITEM_COPY_MARKDOWN)
|
|
76
97
|
menu.removeItem(MENU_ITEM_COPY_IMAGE_URL)
|
|
77
98
|
menu.removeGroup(MENU_ITEM_CUSTOM_GROUP)
|
|
78
99
|
|
|
79
100
|
val selectionMenuConfig = getSelectionMenuConfig()
|
|
101
|
+
val hasSelection = textView.selectionStart >= 0 && textView.selectionEnd > textView.selectionStart
|
|
80
102
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
103
|
+
if (selectionMenuConfig.systemItemsNone) {
|
|
104
|
+
// Editor re-adds Select all and the text-assist items before calling
|
|
105
|
+
// us on every prepare, so clear on each pass and put back only Copy.
|
|
106
|
+
// Its click is still intercepted in onActionItemClicked.
|
|
107
|
+
menu.clear()
|
|
108
|
+
if (selectionMenuConfig.copyEnabled && hasSelection) {
|
|
109
|
+
menu.add(Menu.NONE, android.R.id.copy, Menu.NONE, selectionMenuConfig.copyLabel)
|
|
110
|
+
}
|
|
111
|
+
} else if (!selectionMenuConfig.copyEnabled) {
|
|
112
|
+
menu.removeItem(android.R.id.copy)
|
|
113
|
+
} else if (selectionMenuConfig.copyLabel.isNotEmpty()) {
|
|
114
|
+
// The system Copy item is added by the platform; relabel it so it
|
|
115
|
+
// matches the rest of the localized menu (iOS rebuilds the menu so
|
|
116
|
+
// gets this for free; Android only intercepts the click).
|
|
85
117
|
menu.findItem(android.R.id.copy)?.title = selectionMenuConfig.copyLabel
|
|
86
118
|
}
|
|
87
119
|
|
|
88
|
-
if (
|
|
89
|
-
selectionMenuConfig.copyAsMarkdown &&
|
|
90
|
-
textView.selectionStart >= 0 &&
|
|
91
|
-
textView.selectionEnd > textView.selectionStart
|
|
92
|
-
) {
|
|
120
|
+
if (selectionMenuConfig.copyAsMarkdown && hasSelection) {
|
|
93
121
|
menu.add(
|
|
94
122
|
Menu.NONE,
|
|
95
123
|
MENU_ITEM_COPY_MARKDOWN,
|
|
@@ -98,7 +126,7 @@ fun createSelectionActionModeCallback(
|
|
|
98
126
|
)
|
|
99
127
|
}
|
|
100
128
|
|
|
101
|
-
if (
|
|
129
|
+
if (hasSelection) {
|
|
102
130
|
val customItems = getCustomItemTexts()
|
|
103
131
|
customItems.forEachIndexed { index, text ->
|
|
104
132
|
menu
|
|
@@ -129,7 +157,9 @@ fun createSelectionActionModeCallback(
|
|
|
129
157
|
|
|
130
158
|
when (itemId) {
|
|
131
159
|
android.R.id.copy -> {
|
|
132
|
-
textView.
|
|
160
|
+
if (!getSelectionMenuConfig().copyFormatMarkdown || !textView.copyMarkdownToClipboard()) {
|
|
161
|
+
textView.copyWithHTML()
|
|
162
|
+
}
|
|
133
163
|
mode?.finish()
|
|
134
164
|
return true
|
|
135
165
|
}
|
|
@@ -161,7 +191,9 @@ fun createSelectionActionModeCallback(
|
|
|
161
191
|
return false
|
|
162
192
|
}
|
|
163
193
|
|
|
164
|
-
override fun onDestroyActionMode(mode: ActionMode?) {
|
|
194
|
+
override fun onDestroyActionMode(mode: ActionMode?) {
|
|
195
|
+
onActionModeChanged(null)
|
|
196
|
+
}
|
|
165
197
|
}
|
|
166
198
|
|
|
167
199
|
/** Copies selection as both plain text and HTML with inline styles. */
|
|
@@ -197,10 +229,12 @@ private fun TextView.copyWithHTML() {
|
|
|
197
229
|
}
|
|
198
230
|
}
|
|
199
231
|
|
|
200
|
-
|
|
201
|
-
|
|
232
|
+
/** Returns false when the selection has no Markdown to copy. */
|
|
233
|
+
private fun TextView.copyMarkdownToClipboard(): Boolean {
|
|
234
|
+
val markdown = MarkdownExtractor.getMarkdownForSelection(this) ?: return false
|
|
202
235
|
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
|
203
236
|
clipboard.setPrimaryClip(ClipData.newPlainText("Markdown", markdown))
|
|
237
|
+
return true
|
|
204
238
|
}
|
|
205
239
|
|
|
206
240
|
/** Returns remote image URLs (http/https only) from the current selection. */
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
package com.swmansion.enriched.markdown.views
|
|
2
|
+
|
|
3
|
+
import com.swmansion.enriched.markdown.utils.text.view.SelectionMenuConfig
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Selection-menu options that table, math and code block views need for their
|
|
7
|
+
* own long-press menus. Every default keeps the legacy behavior, so a block view
|
|
8
|
+
* that has not received options yet behaves exactly as before.
|
|
9
|
+
*/
|
|
10
|
+
data class BlockMenuOptions(
|
|
11
|
+
val copyHidden: Boolean = false,
|
|
12
|
+
// The Copy item writes the block's Markdown instead of its raw content.
|
|
13
|
+
val copyWritesMarkdown: Boolean = false,
|
|
14
|
+
val copyAsMarkdownHidden: Boolean = false,
|
|
15
|
+
// Hides the copy button in the code block header.
|
|
16
|
+
val copyButtonHidden: Boolean = false,
|
|
17
|
+
) {
|
|
18
|
+
val hasItems: Boolean get() = !copyHidden || !copyAsMarkdownHidden
|
|
19
|
+
|
|
20
|
+
companion object {
|
|
21
|
+
fun from(config: SelectionMenuConfig) =
|
|
22
|
+
BlockMenuOptions(
|
|
23
|
+
copyHidden = !config.copyEnabled,
|
|
24
|
+
copyWritesMarkdown = config.copyFormatMarkdown,
|
|
25
|
+
copyAsMarkdownHidden = !config.copyAsMarkdown,
|
|
26
|
+
copyButtonHidden = !config.codeBlockCopyButton,
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Adds the Copy / Copy as Markdown items shared by the table, math and code block menus. */
|
|
32
|
+
fun ContextMenuPopup.Builder.blockCopyItems(
|
|
33
|
+
options: BlockMenuOptions,
|
|
34
|
+
copyLabel: String,
|
|
35
|
+
copyAsMarkdownLabel: String,
|
|
36
|
+
copyRaw: () -> Unit,
|
|
37
|
+
copyMarkdown: () -> Unit,
|
|
38
|
+
) {
|
|
39
|
+
if (!options.copyHidden) {
|
|
40
|
+
item(ContextMenuPopup.Icon.COPY, copyLabel, if (options.copyWritesMarkdown) copyMarkdown else copyRaw)
|
|
41
|
+
}
|
|
42
|
+
if (!options.copyAsMarkdownHidden) {
|
|
43
|
+
item(ContextMenuPopup.Icon.DOCUMENT, copyAsMarkdownLabel, copyMarkdown)
|
|
44
|
+
}
|
|
45
|
+
}
|