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
|
@@ -9,29 +9,44 @@ import android.util.AttributeSet
|
|
|
9
9
|
import android.util.Log
|
|
10
10
|
import android.view.View
|
|
11
11
|
import android.widget.FrameLayout
|
|
12
|
+
import com.facebook.react.bridge.Arguments
|
|
12
13
|
import com.facebook.react.bridge.ReadableMap
|
|
14
|
+
import com.facebook.react.uimanager.StateWrapper
|
|
13
15
|
import com.swmansion.enriched.markdown.accessibility.AccessibilityLabels
|
|
14
16
|
import com.swmansion.enriched.markdown.parser.Md4cFlags
|
|
15
17
|
import com.swmansion.enriched.markdown.parser.Parser
|
|
16
18
|
import com.swmansion.enriched.markdown.spoiler.SpoilerOverlay
|
|
17
19
|
import com.swmansion.enriched.markdown.styles.StyleConfig
|
|
18
20
|
import com.swmansion.enriched.markdown.utils.common.BreakStrategyUtils
|
|
21
|
+
import com.swmansion.enriched.markdown.utils.common.CodeBlockStreamingMode
|
|
19
22
|
import com.swmansion.enriched.markdown.utils.common.FeatureFlags
|
|
20
23
|
import com.swmansion.enriched.markdown.utils.common.MarkdownSegmentRenderer
|
|
21
24
|
import com.swmansion.enriched.markdown.utils.common.RenderedSegment
|
|
22
25
|
import com.swmansion.enriched.markdown.utils.common.SegmentReconciler
|
|
23
26
|
import com.swmansion.enriched.markdown.utils.common.StreamingMarkdownFilter
|
|
24
27
|
import com.swmansion.enriched.markdown.utils.common.TableStreamingMode
|
|
28
|
+
import com.swmansion.enriched.markdown.utils.common.emitLinkLayout
|
|
29
|
+
import com.swmansion.enriched.markdown.utils.common.emitSelectionChange
|
|
25
30
|
import com.swmansion.enriched.markdown.utils.common.isReducedMotionEnabled
|
|
26
31
|
import com.swmansion.enriched.markdown.utils.common.splitASTIntoSegments
|
|
27
32
|
import com.swmansion.enriched.markdown.utils.text.TailFadeInAnimator
|
|
33
|
+
import com.swmansion.enriched.markdown.utils.text.view.LinkLayoutCollector
|
|
34
|
+
import com.swmansion.enriched.markdown.utils.text.view.LinkLayoutFragment
|
|
35
|
+
import com.swmansion.enriched.markdown.utils.text.view.SelectionChangeReporter
|
|
28
36
|
import com.swmansion.enriched.markdown.utils.text.view.SelectionMenuConfig
|
|
37
|
+
import com.swmansion.enriched.markdown.utils.text.view.SelectionRect
|
|
38
|
+
import com.swmansion.enriched.markdown.utils.text.view.SelectionSnapshot
|
|
29
39
|
import com.swmansion.enriched.markdown.utils.text.view.applySelectionColors
|
|
40
|
+
import com.swmansion.enriched.markdown.utils.text.view.currentTextSelection
|
|
41
|
+
import com.swmansion.enriched.markdown.views.BlockMenuOptions
|
|
30
42
|
import com.swmansion.enriched.markdown.views.BlockSegmentView
|
|
43
|
+
import com.swmansion.enriched.markdown.views.CodeBlockContainerView
|
|
31
44
|
import com.swmansion.enriched.markdown.views.TableContainerView
|
|
32
45
|
import java.util.EnumSet
|
|
33
46
|
import java.util.concurrent.ExecutorService
|
|
34
47
|
import java.util.concurrent.Executors
|
|
48
|
+
import kotlin.math.ceil
|
|
49
|
+
import kotlin.math.max
|
|
35
50
|
|
|
36
51
|
class EnrichedMarkdown
|
|
37
52
|
@JvmOverloads
|
|
@@ -62,7 +77,12 @@ class EnrichedMarkdown
|
|
|
62
77
|
private val dirtyFlags = EnumSet.noneOf(DirtyFlag::class.java)
|
|
63
78
|
var streamingAnimation: Boolean = false
|
|
64
79
|
|
|
80
|
+
// used to force a Yoga re-measure when a block image resolves its box height
|
|
81
|
+
var stateWrapper: StateWrapper? = null
|
|
82
|
+
private var forceHeightRecalculationCounter = 0
|
|
83
|
+
|
|
65
84
|
var tableStreamingMode: TableStreamingMode = TableStreamingMode.PROGRESSIVE
|
|
85
|
+
var codeBlockStreamingMode: CodeBlockStreamingMode = CodeBlockStreamingMode.PROGRESSIVE
|
|
66
86
|
private var renderPending: Boolean = false
|
|
67
87
|
|
|
68
88
|
var currentMarkdown: String = ""
|
|
@@ -79,18 +99,39 @@ class EnrichedMarkdown
|
|
|
79
99
|
private var allowFontScaling: Boolean = true
|
|
80
100
|
private var maxFontSizeMultiplier: Float = 0f
|
|
81
101
|
private var allowTrailingMargin: Boolean = false
|
|
102
|
+
private var imageRequestHeaders: Map<String, String> = emptyMap()
|
|
82
103
|
private var selectable: Boolean = true
|
|
104
|
+
private var contextMenuHidden: Boolean = false
|
|
83
105
|
private var selectionColor: Int? = null
|
|
84
106
|
private var selectionHandleColor: Int? = null
|
|
85
107
|
private var selectionMenuConfig = SelectionMenuConfig()
|
|
86
108
|
private var accessibilityLabels = AccessibilityLabels()
|
|
87
109
|
private var textBreakStrategy: String = BreakStrategyUtils.DEFAULT_STRATEGY
|
|
110
|
+
private var linkLayoutEnabled = false
|
|
111
|
+
private var lastLinkLayout: List<LinkLayoutFragment>? = null
|
|
112
|
+
|
|
113
|
+
// At most one segment holds a selection; a new one clears the previous.
|
|
114
|
+
private var selectionOwner: EnrichedMarkdownInternalText? = null
|
|
115
|
+
|
|
116
|
+
// A block long-pressed while contextMenuHidden is on, reported as the selection.
|
|
117
|
+
private class ActiveBlock(
|
|
118
|
+
val view: View,
|
|
119
|
+
val source: String,
|
|
120
|
+
val markdown: String,
|
|
121
|
+
val text: String,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
private var activeBlock: ActiveBlock? = null
|
|
125
|
+
private val selectionReporter =
|
|
126
|
+
SelectionChangeReporter(this, ::selectionSnapshot) { snapshot -> emitSelectionChange(this, snapshot) }
|
|
88
127
|
|
|
89
128
|
private var onLinkPressCallback: ((String) -> Unit)? = null
|
|
90
129
|
private var onLinkLongPressCallback: ((String) -> Unit)? = null
|
|
91
130
|
private var onTaskListItemPressCallback: ((Int, Boolean, String) -> Unit)? = null
|
|
131
|
+
private var onCopyPressCallback: ((String, String) -> Unit)? = null
|
|
92
132
|
private var contextMenuItemTexts: List<String> = emptyList()
|
|
93
133
|
var onContextMenuItemPressCallback: ((itemText: String, selectedText: String, selectionStart: Int, selectionEnd: Int) -> Unit)? = null
|
|
134
|
+
var onCopyRequestCallback: ((source: String, markdown: String, text: String, whole: Boolean) -> Unit)? = null
|
|
94
135
|
var spoilerOverlay: SpoilerOverlay = SpoilerOverlay.PARTICLES
|
|
95
136
|
set(value) {
|
|
96
137
|
if (field == value) return
|
|
@@ -99,6 +140,14 @@ class EnrichedMarkdown
|
|
|
99
140
|
it.spoilerOverlay = value
|
|
100
141
|
}
|
|
101
142
|
}
|
|
143
|
+
var enableTaskListItemToggle: Boolean = true
|
|
144
|
+
set(value) {
|
|
145
|
+
if (field == value) return
|
|
146
|
+
field = value
|
|
147
|
+
segmentViews.filterIsInstance<EnrichedMarkdownInternalText>().forEach {
|
|
148
|
+
it.enableTaskListItemToggle = value
|
|
149
|
+
}
|
|
150
|
+
}
|
|
102
151
|
|
|
103
152
|
fun setMarkdownContent(markdown: String) {
|
|
104
153
|
if (currentMarkdown == markdown) return
|
|
@@ -109,6 +158,7 @@ class EnrichedMarkdown
|
|
|
109
158
|
fun setMarkdownStyle(style: ReadableMap?) {
|
|
110
159
|
markdownStyleMap = style
|
|
111
160
|
val newConfig = style?.let { StyleConfig(it, context, allowFontScaling, maxFontSizeMultiplier) }
|
|
161
|
+
newConfig?.imageRequestHeaders = imageRequestHeaders
|
|
112
162
|
if (markdownStyle == newConfig) return
|
|
113
163
|
markdownStyle = newConfig
|
|
114
164
|
dirtyFlags += DirtyFlag.RECREATE_SEGMENTS
|
|
@@ -116,8 +166,18 @@ class EnrichedMarkdown
|
|
|
116
166
|
renderPending = true
|
|
117
167
|
}
|
|
118
168
|
|
|
169
|
+
fun setImageRequestHeaders(headers: Map<String, String>) {
|
|
170
|
+
if (imageRequestHeaders == headers) return
|
|
171
|
+
imageRequestHeaders = headers
|
|
172
|
+
markdownStyle?.imageRequestHeaders = headers
|
|
173
|
+
dirtyFlags += DirtyFlag.RECREATE_SEGMENTS
|
|
174
|
+
renderPending = true
|
|
175
|
+
}
|
|
176
|
+
|
|
119
177
|
fun commitProps() {
|
|
120
178
|
MeasurementStore.updateStreamingTableMode(id, tableStreamingMode)
|
|
179
|
+
MeasurementStore.updateStreamingCodeBlockMode(id, codeBlockStreamingMode)
|
|
180
|
+
MeasurementStore.updateFontScalingSettings(id, allowFontScaling, maxFontSizeMultiplier)
|
|
121
181
|
if (renderPending) {
|
|
122
182
|
renderPending = false
|
|
123
183
|
scheduleRenderIfNeeded()
|
|
@@ -146,6 +206,7 @@ class EnrichedMarkdown
|
|
|
146
206
|
fun setAllowFontScaling(allow: Boolean) {
|
|
147
207
|
if (allowFontScaling == allow) return
|
|
148
208
|
allowFontScaling = allow
|
|
209
|
+
MeasurementStore.updateFontScalingSettings(id, allowFontScaling, maxFontSizeMultiplier)
|
|
149
210
|
recreateStyleConfig()
|
|
150
211
|
dirtyFlags += DirtyFlag.RECREATE_SEGMENTS
|
|
151
212
|
dirtyFlags += DirtyFlag.FORCE_HEIGHT
|
|
@@ -155,6 +216,7 @@ class EnrichedMarkdown
|
|
|
155
216
|
fun setMaxFontSizeMultiplier(multiplier: Float) {
|
|
156
217
|
if (maxFontSizeMultiplier == multiplier) return
|
|
157
218
|
maxFontSizeMultiplier = multiplier
|
|
219
|
+
MeasurementStore.updateFontScalingSettings(id, allowFontScaling, maxFontSizeMultiplier)
|
|
158
220
|
recreateStyleConfig()
|
|
159
221
|
dirtyFlags += DirtyFlag.RECREATE_SEGMENTS
|
|
160
222
|
dirtyFlags += DirtyFlag.FORCE_HEIGHT
|
|
@@ -177,6 +239,42 @@ class EnrichedMarkdown
|
|
|
177
239
|
}
|
|
178
240
|
}
|
|
179
241
|
|
|
242
|
+
fun setContextMenuHidden(value: Boolean) {
|
|
243
|
+
if (contextMenuHidden == value) return
|
|
244
|
+
contextMenuHidden = value
|
|
245
|
+
applyContextMenuHiddenToSegments()
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Fans the flag out to every segment that owns a copy menu: text segments
|
|
250
|
+
* (floating ActionMode toolbar), tables, code blocks and math blocks (all use
|
|
251
|
+
* their own long-press popup, so none is covered by the ActionMode callback).
|
|
252
|
+
*/
|
|
253
|
+
private fun applyContextMenuHiddenToSegments() {
|
|
254
|
+
segmentViews.forEach { view ->
|
|
255
|
+
when {
|
|
256
|
+
view is EnrichedMarkdownInternalText -> view.contextMenuHidden = contextMenuHidden
|
|
257
|
+
view is TableContainerView -> view.contextMenuHidden = contextMenuHidden
|
|
258
|
+
view is CodeBlockContainerView -> view.contextMenuHidden = contextMenuHidden
|
|
259
|
+
isMathContainerView(view) -> setMathContextMenuHidden(view)
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* MathContainerView lives in the optional `math` source set, so it is only
|
|
266
|
+
* reachable reflectively. The Kotlin `var` compiles to a setter taking a
|
|
267
|
+
* primitive boolean — `Boolean::class.java` would resolve to
|
|
268
|
+
* `java.lang.Boolean` and silently miss.
|
|
269
|
+
*/
|
|
270
|
+
private fun setMathContextMenuHidden(view: View) {
|
|
271
|
+
runCatching {
|
|
272
|
+
view.javaClass
|
|
273
|
+
.getMethod("setContextMenuHidden", Boolean::class.javaPrimitiveType)
|
|
274
|
+
.invoke(view, contextMenuHidden)
|
|
275
|
+
}.onFailure { Log.e(TAG, "Failed to set contextMenuHidden on math view", it) }
|
|
276
|
+
}
|
|
277
|
+
|
|
180
278
|
fun setSelectionColor(color: Int?) {
|
|
181
279
|
if (selectionColor == color) return
|
|
182
280
|
selectionColor = color
|
|
@@ -221,6 +319,10 @@ class EnrichedMarkdown
|
|
|
221
319
|
onTaskListItemPressCallback = callback
|
|
222
320
|
}
|
|
223
321
|
|
|
322
|
+
fun setOnCopyPressCallback(callback: ((code: String, language: String) -> Unit)?) {
|
|
323
|
+
onCopyPressCallback = callback
|
|
324
|
+
}
|
|
325
|
+
|
|
224
326
|
fun setContextMenuItems(items: List<String>) {
|
|
225
327
|
contextMenuItemTexts = items
|
|
226
328
|
segmentViews.filterIsInstance<EnrichedMarkdownInternalText>().forEach {
|
|
@@ -234,8 +336,8 @@ class EnrichedMarkdown
|
|
|
234
336
|
segmentViews.filterIsInstance<EnrichedMarkdownInternalText>().forEach {
|
|
235
337
|
it.selectionMenuConfig = config
|
|
236
338
|
}
|
|
237
|
-
//
|
|
238
|
-
// (e.g. a language change without a remount) to avoid stale
|
|
339
|
+
// Block views cache the copy labels and menu options, so re-push them on
|
|
340
|
+
// update (e.g. a language change without a remount) to avoid stale values.
|
|
239
341
|
pushCopyLabelsToBlockSegments()
|
|
240
342
|
}
|
|
241
343
|
|
|
@@ -247,6 +349,13 @@ class EnrichedMarkdown
|
|
|
247
349
|
view is TableContainerView -> {
|
|
248
350
|
view.copyLabel = copyLabel
|
|
249
351
|
view.copyAsMarkdownLabel = copyAsMarkdownLabel
|
|
352
|
+
view.menuOptions = blockMenuOptions("table")
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
view is CodeBlockContainerView -> {
|
|
356
|
+
view.copyLabel = copyLabel
|
|
357
|
+
view.copyAsMarkdownLabel = copyAsMarkdownLabel
|
|
358
|
+
view.menuOptions = blockMenuOptions("code")
|
|
250
359
|
}
|
|
251
360
|
|
|
252
361
|
isMathContainerView(view) -> {
|
|
@@ -255,6 +364,9 @@ class EnrichedMarkdown
|
|
|
255
364
|
view.javaClass
|
|
256
365
|
.getMethod("setCopyAsMarkdownLabel", String::class.java)
|
|
257
366
|
.invoke(view, copyAsMarkdownLabel)
|
|
367
|
+
view.javaClass
|
|
368
|
+
.getMethod("setMenuOptions", BlockMenuOptions::class.java)
|
|
369
|
+
.invoke(view, blockMenuOptions("math"))
|
|
258
370
|
}
|
|
259
371
|
}
|
|
260
372
|
}
|
|
@@ -281,6 +393,22 @@ class EnrichedMarkdown
|
|
|
281
393
|
}
|
|
282
394
|
}
|
|
283
395
|
|
|
396
|
+
private fun blockMenuOptions(source: String) =
|
|
397
|
+
BlockMenuOptions.from(selectionMenuConfig) { markdown, text ->
|
|
398
|
+
onCopyRequestCallback?.invoke(source, markdown, text, true)
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Segments only see their own text, so a selection is the whole component
|
|
402
|
+
// only when it spans the sole segment; the markdown is then the original.
|
|
403
|
+
private fun forwardSegmentCopyRequest(
|
|
404
|
+
markdown: String,
|
|
405
|
+
text: String,
|
|
406
|
+
fullSelection: Boolean,
|
|
407
|
+
) {
|
|
408
|
+
val whole = fullSelection && segmentViews.size == 1 && currentMarkdown.isNotEmpty()
|
|
409
|
+
onCopyRequestCallback?.invoke("selection", if (whole) currentMarkdown else markdown, text, whole)
|
|
410
|
+
}
|
|
411
|
+
|
|
284
412
|
private fun forwardContextMenuItemPress(
|
|
285
413
|
itemText: String,
|
|
286
414
|
selectedText: String,
|
|
@@ -290,9 +418,84 @@ class EnrichedMarkdown
|
|
|
290
418
|
onContextMenuItemPressCallback?.invoke(itemText, selectedText, selectionStart, selectionEnd)
|
|
291
419
|
}
|
|
292
420
|
|
|
421
|
+
fun setEmitSelectionChange(enabled: Boolean) {
|
|
422
|
+
selectionReporter.enabled = enabled
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/** Clears the selection of every segment (and any active block) and reports `active: false`. */
|
|
426
|
+
fun clearSelection() {
|
|
427
|
+
val owner = selectionOwner
|
|
428
|
+
selectionOwner = null
|
|
429
|
+
activeBlock = null
|
|
430
|
+
owner?.clearSelection()
|
|
431
|
+
selectionReporter.flushNow()
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
private fun onSegmentSelectionChanged(
|
|
435
|
+
view: EnrichedMarkdownInternalText,
|
|
436
|
+
hasSelection: Boolean,
|
|
437
|
+
) {
|
|
438
|
+
if (hasSelection) {
|
|
439
|
+
// Take ownership first so the previous owner's own "cleared" callback is ignored.
|
|
440
|
+
val previous = selectionOwner
|
|
441
|
+
selectionOwner = view
|
|
442
|
+
activeBlock = null
|
|
443
|
+
if (previous !== view) previous?.clearSelection()
|
|
444
|
+
selectionReporter.schedule()
|
|
445
|
+
} else if (selectionOwner === view) {
|
|
446
|
+
selectionReporter.onSelectionChanged(false)
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
private fun onBlockMenuSuppressed(
|
|
451
|
+
view: View,
|
|
452
|
+
source: String,
|
|
453
|
+
markdown: String,
|
|
454
|
+
text: String,
|
|
455
|
+
) {
|
|
456
|
+
if (!selectionReporter.enabled) return
|
|
457
|
+
val previous = selectionOwner
|
|
458
|
+
selectionOwner = null
|
|
459
|
+
previous?.clearSelection()
|
|
460
|
+
activeBlock = ActiveBlock(view, source, markdown, text)
|
|
461
|
+
selectionReporter.forgetLastReported()
|
|
462
|
+
selectionReporter.flushNow()
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
private fun selectionSnapshot(): SelectionSnapshot {
|
|
466
|
+
activeBlock?.let { block ->
|
|
467
|
+
if (block.view.parent !== this) return SelectionSnapshot.INACTIVE
|
|
468
|
+
val rect =
|
|
469
|
+
SelectionRect.fromPx(
|
|
470
|
+
block.view.left.toFloat(),
|
|
471
|
+
block.view.top.toFloat(),
|
|
472
|
+
block.view.right.toFloat(),
|
|
473
|
+
block.view.bottom.toFloat(),
|
|
474
|
+
)
|
|
475
|
+
return SelectionSnapshot.block(block.source, block.markdown, block.text, rect)
|
|
476
|
+
}
|
|
477
|
+
val owner = selectionOwner?.takeIf { it.parent === this } ?: return SelectionSnapshot.INACTIVE
|
|
478
|
+
val selection = owner.currentTextSelection(owner.left, owner.top) ?: return SelectionSnapshot.INACTIVE
|
|
479
|
+
// Same rule as forwardSegmentCopyRequest.
|
|
480
|
+
val whole = selection.fullSelection && segmentViews.size == 1 && currentMarkdown.isNotEmpty()
|
|
481
|
+
return SelectionSnapshot(
|
|
482
|
+
active = true,
|
|
483
|
+
source = "selection",
|
|
484
|
+
text = selection.text,
|
|
485
|
+
markdown = if (whole) currentMarkdown else selection.markdown,
|
|
486
|
+
whole = whole,
|
|
487
|
+
rect = selection.rect,
|
|
488
|
+
startRect = selection.startRect,
|
|
489
|
+
endRect = selection.endRect,
|
|
490
|
+
)
|
|
491
|
+
}
|
|
492
|
+
|
|
293
493
|
private fun recreateStyleConfig() {
|
|
294
494
|
markdownStyleMap?.let {
|
|
295
|
-
markdownStyle =
|
|
495
|
+
markdownStyle =
|
|
496
|
+
StyleConfig(it, context, allowFontScaling, maxFontSizeMultiplier).also { config ->
|
|
497
|
+
config.imageRequestHeaders = imageRequestHeaders
|
|
498
|
+
}
|
|
296
499
|
}
|
|
297
500
|
}
|
|
298
501
|
|
|
@@ -305,26 +508,29 @@ class EnrichedMarkdown
|
|
|
305
508
|
val markdown = currentMarkdown.takeIf { it.isNotEmpty() } ?: return
|
|
306
509
|
val isStreaming = streamingAnimation
|
|
307
510
|
val tableMode = tableStreamingMode
|
|
511
|
+
val codeBlockMode = codeBlockStreamingMode
|
|
308
512
|
|
|
309
513
|
val renderId = ++currentRenderId
|
|
310
514
|
|
|
311
515
|
executor.execute {
|
|
312
516
|
try {
|
|
313
|
-
val
|
|
517
|
+
val filtered =
|
|
314
518
|
if (isStreaming) {
|
|
315
|
-
StreamingMarkdownFilter.renderableMarkdownForStreaming(markdown, tableMode)
|
|
519
|
+
StreamingMarkdownFilter.renderableMarkdownForStreaming(markdown, tableMode, codeBlockMode)
|
|
316
520
|
} else {
|
|
317
|
-
|
|
521
|
+
null
|
|
318
522
|
}
|
|
523
|
+
val renderableMarkdown = filtered?.markdown ?: markdown
|
|
524
|
+
val hasPendingCodeBlock = filtered?.endsInsideOpenCodeFence ?: false
|
|
319
525
|
|
|
320
526
|
if (renderableMarkdown.isEmpty()) {
|
|
321
|
-
postToMain(renderId) { applyRenderedSegments(emptyList(), style) }
|
|
527
|
+
postToMain(renderId) { applyRenderedSegments(emptyList(), style, false) }
|
|
322
528
|
return@execute
|
|
323
529
|
}
|
|
324
530
|
|
|
325
531
|
val ast =
|
|
326
532
|
parser.parseMarkdown(renderableMarkdown, md4cFlags) ?: run {
|
|
327
|
-
postToMain(renderId) { applyRenderedSegments(emptyList(), style) }
|
|
533
|
+
postToMain(renderId) { applyRenderedSegments(emptyList(), style, false) }
|
|
328
534
|
return@execute
|
|
329
535
|
}
|
|
330
536
|
|
|
@@ -338,18 +544,25 @@ class EnrichedMarkdown
|
|
|
338
544
|
onLinkLongPressCallback,
|
|
339
545
|
)
|
|
340
546
|
|
|
341
|
-
postToMain(renderId) { applyRenderedSegments(renderedSegments, style) }
|
|
547
|
+
postToMain(renderId) { applyRenderedSegments(renderedSegments, style, hasPendingCodeBlock) }
|
|
342
548
|
} catch (e: Exception) {
|
|
343
549
|
Log.e(TAG, "Render failed", e)
|
|
344
|
-
postToMain(renderId) { applyRenderedSegments(emptyList(), style) }
|
|
550
|
+
postToMain(renderId) { applyRenderedSegments(emptyList(), style, false) }
|
|
345
551
|
}
|
|
346
552
|
}
|
|
347
553
|
}
|
|
348
554
|
|
|
555
|
+
// Trailing code block whose closing fence hasn't streamed in yet, if any.
|
|
556
|
+
private var pendingCodeBlockSegment: RenderedSegment.CodeBlock? = null
|
|
557
|
+
|
|
349
558
|
private fun applyRenderedSegments(
|
|
350
559
|
renderedSegments: List<RenderedSegment>,
|
|
351
560
|
style: StyleConfig,
|
|
561
|
+
hasPendingCodeBlock: Boolean,
|
|
352
562
|
) {
|
|
563
|
+
pendingCodeBlockSegment =
|
|
564
|
+
if (hasPendingCodeBlock) renderedSegments.lastOrNull() as? RenderedSegment.CodeBlock else null
|
|
565
|
+
|
|
353
566
|
val reset = DirtyFlag.RECREATE_SEGMENTS in dirtyFlags
|
|
354
567
|
val forceHeight = DirtyFlag.FORCE_HEIGHT in dirtyFlags
|
|
355
568
|
dirtyFlags.clear()
|
|
@@ -377,6 +590,17 @@ class EnrichedMarkdown
|
|
|
377
590
|
segmentSignatures.clear()
|
|
378
591
|
segmentSignatures.addAll(result.signatures)
|
|
379
592
|
|
|
593
|
+
if (selectionOwner?.let { owner -> segmentViews.none { it === owner } } == true) selectionOwner = null
|
|
594
|
+
if (activeBlock?.let { block -> segmentViews.none { it === block.view } } == true) activeBlock = null
|
|
595
|
+
|
|
596
|
+
// A just-closed block has unchanged content, so the reconciler reuses it
|
|
597
|
+
// without an update; sync pending here to trigger its deferred highlight.
|
|
598
|
+
segmentViews.forEachIndexed { index, view ->
|
|
599
|
+
if (view is CodeBlockContainerView) {
|
|
600
|
+
view.pending = pendingCodeBlockSegment != null && index == segmentViews.size - 1
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
380
604
|
val topologyChanged = result.viewsToAttach.isNotEmpty() || result.viewsToRemove.isNotEmpty()
|
|
381
605
|
|
|
382
606
|
if (width > 0) {
|
|
@@ -399,6 +623,7 @@ class EnrichedMarkdown
|
|
|
399
623
|
is RenderedSegment.Text -> view is EnrichedMarkdownInternalText
|
|
400
624
|
is RenderedSegment.Table -> view is TableContainerView
|
|
401
625
|
is RenderedSegment.Math -> isMathContainerView(view)
|
|
626
|
+
is RenderedSegment.CodeBlock -> view is CodeBlockContainerView
|
|
402
627
|
}
|
|
403
628
|
|
|
404
629
|
private fun isMathContainerView(view: View): Boolean = mathContainerClass?.isInstance(view) == true
|
|
@@ -411,6 +636,7 @@ class EnrichedMarkdown
|
|
|
411
636
|
is RenderedSegment.Text -> createTextView(segment)
|
|
412
637
|
is RenderedSegment.Table -> createTableView(segment, style)
|
|
413
638
|
is RenderedSegment.Math -> createMathView(segment, style)
|
|
639
|
+
is RenderedSegment.CodeBlock -> createCodeBlockView(segment, style)
|
|
414
640
|
}
|
|
415
641
|
|
|
416
642
|
private fun updateSegmentView(
|
|
@@ -441,6 +667,13 @@ class EnrichedMarkdown
|
|
|
441
667
|
?.getMethod("applyLatex", String::class.java)
|
|
442
668
|
?.invoke(view, segment.latex)
|
|
443
669
|
}
|
|
670
|
+
|
|
671
|
+
is RenderedSegment.CodeBlock -> {
|
|
672
|
+
(view as CodeBlockContainerView).apply {
|
|
673
|
+
pending = segment === pendingCodeBlockSegment
|
|
674
|
+
applyCodeBlockNode(segment.node)
|
|
675
|
+
}
|
|
676
|
+
}
|
|
444
677
|
}
|
|
445
678
|
}
|
|
446
679
|
|
|
@@ -451,7 +684,7 @@ class EnrichedMarkdown
|
|
|
451
684
|
if (!streamingAnimation) return
|
|
452
685
|
when (segment) {
|
|
453
686
|
is RenderedSegment.Text -> animateTextViewTail(view as EnrichedMarkdownInternalText, 0)
|
|
454
|
-
is RenderedSegment.Table, is RenderedSegment.Math -> animateBlockViewFadeIn(view)
|
|
687
|
+
is RenderedSegment.Table, is RenderedSegment.Math, is RenderedSegment.CodeBlock -> animateBlockViewFadeIn(view)
|
|
455
688
|
}
|
|
456
689
|
}
|
|
457
690
|
|
|
@@ -479,9 +712,12 @@ class EnrichedMarkdown
|
|
|
479
712
|
private fun createTextView(segment: RenderedSegment.Text) =
|
|
480
713
|
EnrichedMarkdownInternalText(context).apply {
|
|
481
714
|
spoilerOverlay = this@EnrichedMarkdown.spoilerOverlay
|
|
715
|
+
enableTaskListItemToggle = this@EnrichedMarkdown.enableTaskListItemToggle
|
|
482
716
|
selectionMenuConfig = this@EnrichedMarkdown.selectionMenuConfig
|
|
717
|
+
contextMenuHidden = this@EnrichedMarkdown.contextMenuHidden
|
|
483
718
|
accessibilityLabels = this@EnrichedMarkdown.accessibilityLabels
|
|
484
719
|
setIsSelectable(selectable)
|
|
720
|
+
markdownStyle?.paragraphStyle?.fontSize?.let { setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, it) }
|
|
485
721
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
486
722
|
breakStrategy = BreakStrategyUtils.resolveBreakStrategy(textBreakStrategy)
|
|
487
723
|
}
|
|
@@ -495,6 +731,8 @@ class EnrichedMarkdown
|
|
|
495
731
|
onTaskListItemPressCallback = { taskIndex, checked, itemText ->
|
|
496
732
|
this@EnrichedMarkdown.onTaskListItemPressCallback?.invoke(taskIndex, checked, itemText)
|
|
497
733
|
}
|
|
734
|
+
onCopyRequest = ::forwardSegmentCopyRequest
|
|
735
|
+
onSelectionChangedCallback = ::onSegmentSelectionChanged
|
|
498
736
|
|
|
499
737
|
if (contextMenuItemTexts.isNotEmpty()) {
|
|
500
738
|
setContextMenuItems(contextMenuItemTexts, ::forwardContextMenuItemPress)
|
|
@@ -514,9 +752,28 @@ class EnrichedMarkdown
|
|
|
514
752
|
onLinkLongPress = onLinkLongPressCallback
|
|
515
753
|
copyLabel = this@EnrichedMarkdown.selectionMenuConfig.copyLabel
|
|
516
754
|
copyAsMarkdownLabel = this@EnrichedMarkdown.selectionMenuConfig.copyAsMarkdownLabel
|
|
755
|
+
contextMenuHidden = this@EnrichedMarkdown.contextMenuHidden
|
|
756
|
+
menuOptions = blockMenuOptions("table")
|
|
757
|
+
onMenuSuppressed = { markdown, text -> onBlockMenuSuppressed(this, "table", markdown, text) }
|
|
517
758
|
applyTableNode(segment.node)
|
|
518
759
|
}
|
|
519
760
|
|
|
761
|
+
private fun createCodeBlockView(
|
|
762
|
+
segment: RenderedSegment.CodeBlock,
|
|
763
|
+
style: StyleConfig,
|
|
764
|
+
) = CodeBlockContainerView(context, style).apply {
|
|
765
|
+
copyLabel = this@EnrichedMarkdown.selectionMenuConfig.copyLabel
|
|
766
|
+
copyAsMarkdownLabel = this@EnrichedMarkdown.selectionMenuConfig.copyAsMarkdownLabel
|
|
767
|
+
contextMenuHidden = this@EnrichedMarkdown.contextMenuHidden
|
|
768
|
+
menuOptions = blockMenuOptions("code")
|
|
769
|
+
onMenuSuppressed = { markdown, text -> onBlockMenuSuppressed(this, "code", markdown, text) }
|
|
770
|
+
onCopyPress = { code, language ->
|
|
771
|
+
this@EnrichedMarkdown.onCopyPressCallback?.invoke(code, language)
|
|
772
|
+
}
|
|
773
|
+
pending = segment === pendingCodeBlockSegment
|
|
774
|
+
applyCodeBlockNode(segment.node)
|
|
775
|
+
}
|
|
776
|
+
|
|
520
777
|
private fun createMathView(
|
|
521
778
|
segment: RenderedSegment.Math,
|
|
522
779
|
style: StyleConfig,
|
|
@@ -539,6 +796,16 @@ class EnrichedMarkdown
|
|
|
539
796
|
resolvedClass
|
|
540
797
|
.getMethod("setCopyAsMarkdownLabel", String::class.java)
|
|
541
798
|
.invoke(view, selectionMenuConfig.copyAsMarkdownLabel)
|
|
799
|
+
resolvedClass
|
|
800
|
+
.getMethod("setMenuOptions", BlockMenuOptions::class.java)
|
|
801
|
+
.invoke(view, blockMenuOptions("math"))
|
|
802
|
+
setMathContextMenuHidden(view)
|
|
803
|
+
val onMenuSuppressed: (String, String) -> Unit = { markdown, text ->
|
|
804
|
+
onBlockMenuSuppressed(view, "math", markdown, text)
|
|
805
|
+
}
|
|
806
|
+
runCatching {
|
|
807
|
+
resolvedClass.getMethod("setOnMenuSuppressed", Function2::class.java).invoke(view, onMenuSuppressed)
|
|
808
|
+
}.onFailure { Log.e(TAG, "Failed to set onMenuSuppressed on math view", it) }
|
|
542
809
|
resolvedClass.getMethod("applyLatex", String::class.java).invoke(view, segment.latex)
|
|
543
810
|
view
|
|
544
811
|
} catch (e: Exception) {
|
|
@@ -566,10 +833,31 @@ class EnrichedMarkdown
|
|
|
566
833
|
layoutSegments()
|
|
567
834
|
}
|
|
568
835
|
|
|
836
|
+
fun onImageLayoutChanged() {
|
|
837
|
+
if (width > 0) {
|
|
838
|
+
layoutSegments()
|
|
839
|
+
requestLayout()
|
|
840
|
+
}
|
|
841
|
+
MeasurementStore.invalidate(id)
|
|
842
|
+
val wrapper = stateWrapper ?: return
|
|
843
|
+
val state = Arguments.createMap()
|
|
844
|
+
state.putInt("forceHeightRecalculationCounter", ++forceHeightRecalculationCounter)
|
|
845
|
+
wrapper.updateState(state)
|
|
846
|
+
}
|
|
847
|
+
|
|
569
848
|
private fun layoutSegments() {
|
|
570
849
|
val containerWidth = width
|
|
571
850
|
if (containerWidth <= 0) return
|
|
572
851
|
|
|
852
|
+
val needsOverhang =
|
|
853
|
+
segmentViews.any { view ->
|
|
854
|
+
view is TableContainerView &&
|
|
855
|
+
ceil(view.tableStyle.horizontalOverflow.toDouble()).toInt() > 0
|
|
856
|
+
}
|
|
857
|
+
if (clipChildren == needsOverhang) {
|
|
858
|
+
clipChildren = !needsOverhang
|
|
859
|
+
}
|
|
860
|
+
|
|
573
861
|
var currentY = 0
|
|
574
862
|
val lastIndex = segmentViews.lastIndex
|
|
575
863
|
val widthSpec = MeasureSpec.makeMeasureSpec(containerWidth, MeasureSpec.EXACTLY)
|
|
@@ -580,15 +868,64 @@ class EnrichedMarkdown
|
|
|
580
868
|
val shouldAddBottomMargin = index != lastIndex || allowTrailingMargin
|
|
581
869
|
|
|
582
870
|
currentY += segment?.segmentMarginTop ?: 0
|
|
583
|
-
view.measure(widthSpec, heightSpec)
|
|
584
871
|
|
|
585
|
-
|
|
872
|
+
val overhang =
|
|
873
|
+
if (view is TableContainerView) {
|
|
874
|
+
max(ceil(view.tableStyle.horizontalOverflow.toDouble()).toInt(), 0)
|
|
875
|
+
} else {
|
|
876
|
+
0
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
if (overhang > 0) {
|
|
880
|
+
val extendedWidth = containerWidth + overhang * 2
|
|
881
|
+
val extWidthSpec = MeasureSpec.makeMeasureSpec(extendedWidth, MeasureSpec.EXACTLY)
|
|
882
|
+
view.measure(extWidthSpec, heightSpec)
|
|
883
|
+
view.layout(-overhang, currentY, containerWidth + overhang, currentY + view.measuredHeight)
|
|
884
|
+
} else {
|
|
885
|
+
view.measure(widthSpec, heightSpec)
|
|
886
|
+
view.layout(0, currentY, containerWidth, currentY + view.measuredHeight)
|
|
887
|
+
}
|
|
586
888
|
currentY += view.measuredHeight
|
|
587
889
|
|
|
588
890
|
if (shouldAddBottomMargin) {
|
|
589
891
|
currentY += segment?.segmentMarginBottom ?: 0
|
|
590
892
|
}
|
|
591
893
|
}
|
|
894
|
+
|
|
895
|
+
emitLinkLayoutIfNeeded()
|
|
896
|
+
// Segments may have moved or been replaced; re-read the selection (deduplicated).
|
|
897
|
+
if (selectionOwner != null || activeBlock != null) selectionReporter.schedule() else selectionReporter.flushNow()
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
fun setEmitLinkLayout(enabled: Boolean) {
|
|
901
|
+
if (linkLayoutEnabled == enabled) return
|
|
902
|
+
linkLayoutEnabled = enabled
|
|
903
|
+
lastLinkLayout = null
|
|
904
|
+
emitLinkLayoutIfNeeded()
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
/**
|
|
908
|
+
* Reports link rects of every text segment (offset by the segment's position) to JS for
|
|
909
|
+
* `renderLinkDecoration`. Tables are skipped: their cells scroll horizontally, so rects would
|
|
910
|
+
* go stale. Runs after each segment layout pass; deduplicated so an unchanged layout sends nothing.
|
|
911
|
+
*/
|
|
912
|
+
private fun emitLinkLayoutIfNeeded() {
|
|
913
|
+
if (!linkLayoutEnabled || width <= 0) return
|
|
914
|
+
val fragments = mutableListOf<LinkLayoutFragment>()
|
|
915
|
+
var linkCount = 0
|
|
916
|
+
segmentViews.forEach { view ->
|
|
917
|
+
if (view is TableContainerView) {
|
|
918
|
+
linkCount += view.linkCount
|
|
919
|
+
return@forEach
|
|
920
|
+
}
|
|
921
|
+
if (view !is EnrichedMarkdownInternalText) return@forEach
|
|
922
|
+
val (segmentFragments, segmentLinks) = LinkLayoutCollector.collect(view, view.left, view.top, linkCount)
|
|
923
|
+
fragments += segmentFragments
|
|
924
|
+
linkCount += segmentLinks
|
|
925
|
+
}
|
|
926
|
+
if (fragments == lastLinkLayout) return
|
|
927
|
+
lastLinkLayout = fragments
|
|
928
|
+
emitLinkLayout(this, fragments)
|
|
592
929
|
}
|
|
593
930
|
|
|
594
931
|
private fun computeSegmentsTotalHeight(): Int {
|
|
@@ -606,6 +943,7 @@ class EnrichedMarkdown
|
|
|
606
943
|
}
|
|
607
944
|
|
|
608
945
|
fun cleanup() {
|
|
946
|
+
selectionReporter.cancel()
|
|
609
947
|
executor.shutdownNow()
|
|
610
948
|
}
|
|
611
949
|
|