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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#import "EditMenuUtils.h"
|
|
2
|
+
#import "ENRMLinkChip.h"
|
|
2
3
|
#import "PasteboardUtils.h"
|
|
3
4
|
#import "StyleConfig.h"
|
|
4
5
|
#include <TargetConditionals.h>
|
|
@@ -10,14 +11,34 @@ static NSString *const kActionIdentifierCopy = @"com.swmansion.enriched.markdown
|
|
|
10
11
|
static NSString *const kActionIdentifierCopyMarkdown = @"com.swmansion.enriched.markdown.copyMarkdown";
|
|
11
12
|
static NSString *const kActionIdentifierCopyImageURL = @"com.swmansion.enriched.markdown.copyImageURL";
|
|
12
13
|
|
|
13
|
-
static UIAction *createCopyAction(NSAttributedString *selectedText, NSString *markdown,
|
|
14
|
-
|
|
14
|
+
static UIAction *_Nullable createCopyAction(NSAttributedString *selectedText, NSString *markdown, BOOL fullSelection,
|
|
15
|
+
StyleConfig *styleConfig, ENRMSelectionMenuConfig selectionMenuConfig,
|
|
16
|
+
ENRMCopyRequestHandler _Nullable onCopyRequest)
|
|
15
17
|
{
|
|
16
|
-
|
|
18
|
+
if (!selectionMenuConfig.copyEnabled)
|
|
19
|
+
return nil;
|
|
20
|
+
|
|
21
|
+
if (selectionMenuConfig.interceptCopy && onCopyRequest) {
|
|
22
|
+
NSString *text = selectedText.string;
|
|
23
|
+
NSString *copied = markdown.length > 0 ? markdown : text;
|
|
24
|
+
return [UIAction actionWithTitle:selectionMenuConfig.copyLabel
|
|
25
|
+
image:[RCTUIImage systemImageNamed:@"doc.on.doc"]
|
|
26
|
+
identifier:kActionIdentifierCopy
|
|
27
|
+
handler:^(__kindof UIAction *action) { onCopyRequest(copied, text, fullSelection); }];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
BOOL writesMarkdown = selectionMenuConfig.copyFormatMarkdown;
|
|
31
|
+
return [UIAction actionWithTitle:selectionMenuConfig.copyLabel
|
|
17
32
|
image:[RCTUIImage systemImageNamed:@"doc.on.doc"]
|
|
18
33
|
identifier:kActionIdentifierCopy
|
|
19
34
|
handler:^(__kindof UIAction *action) {
|
|
20
|
-
|
|
35
|
+
if (!writesMarkdown) {
|
|
36
|
+
copyAttributedStringToPasteboard(selectedText, markdown, styleConfig);
|
|
37
|
+
} else {
|
|
38
|
+
// Plain text only: with HTML/RTF alongside, rich-paste targets
|
|
39
|
+
// would take those and drop the Markdown.
|
|
40
|
+
copyStringToPasteboard(markdown.length > 0 ? markdown : selectedText.string);
|
|
41
|
+
}
|
|
21
42
|
}];
|
|
22
43
|
}
|
|
23
44
|
|
|
@@ -47,13 +68,37 @@ static UIAction *_Nullable createCopyImageURLAction(NSArray<NSString *> *imageUR
|
|
|
47
68
|
handler:^(__kindof UIAction *action) { copyStringToPasteboard(urlsToCopy); }];
|
|
48
69
|
}
|
|
49
70
|
|
|
50
|
-
|
|
71
|
+
/// Rebuilds the standard-edit menu with the system Copy swapped for the enhanced
|
|
72
|
+
/// copy action, or dropped when `copyAction` is nil (Copy disabled). All other
|
|
73
|
+
/// system items are kept — dropping them would remove Select All, which on
|
|
74
|
+
/// iOS 16+ is the only way to start a selection from the long-press menu of a
|
|
75
|
+
/// non-editable text view.
|
|
76
|
+
static UIMenu *createEnhancedStandardEditMenu(UIMenu *originalMenu, UIAction *_Nullable copyAction)
|
|
51
77
|
{
|
|
78
|
+
NSMutableArray<UIMenuElement *> *children = [NSMutableArray arrayWithCapacity:originalMenu.children.count];
|
|
79
|
+
BOOL replacedCopy = NO;
|
|
80
|
+
|
|
81
|
+
for (UIMenuElement *element in originalMenu.children) {
|
|
82
|
+
if (!replacedCopy && [element isKindOfClass:[UICommand class]] &&
|
|
83
|
+
((UICommand *)element).action == @selector(copy:)) {
|
|
84
|
+
if (copyAction) {
|
|
85
|
+
[children addObject:copyAction];
|
|
86
|
+
}
|
|
87
|
+
replacedCopy = YES;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
[children addObject:element];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (!replacedCopy && copyAction) {
|
|
94
|
+
[children insertObject:copyAction atIndex:0];
|
|
95
|
+
}
|
|
96
|
+
|
|
52
97
|
return [UIMenu menuWithTitle:originalMenu.title
|
|
53
98
|
image:originalMenu.image
|
|
54
99
|
identifier:originalMenu.identifier
|
|
55
100
|
options:originalMenu.options
|
|
56
|
-
children
|
|
101
|
+
children:children];
|
|
57
102
|
}
|
|
58
103
|
|
|
59
104
|
static void addOptionalAction(NSMutableArray<UIMenuElement *> *array, UIAction *_Nullable action)
|
|
@@ -74,13 +119,19 @@ static void insertOptionalAction(NSMutableArray<UIMenuElement *> *array, UIActio
|
|
|
74
119
|
UIMenu *buildEditMenuForSelection(NSAttributedString *attributedText, NSRange range, NSString *_Nullable cachedMarkdown,
|
|
75
120
|
StyleConfig *styleConfig, NSArray<UIMenuElement *> *suggestedActions,
|
|
76
121
|
NSArray<UIAction *> *_Nullable customActions,
|
|
77
|
-
ENRMSelectionMenuConfig selectionMenuConfig
|
|
122
|
+
ENRMSelectionMenuConfig selectionMenuConfig,
|
|
123
|
+
ENRMCopyRequestHandler _Nullable onCopyRequest) API_AVAILABLE(ios(16.0))
|
|
78
124
|
{
|
|
79
|
-
|
|
125
|
+
// Link spacers only reserve layout space; keep them out of every copied flavor.
|
|
126
|
+
NSAttributedString *selectedText =
|
|
127
|
+
ENRMAttributedStringByRemovingLinkSpacers([attributedText attributedSubstringFromRange:range]);
|
|
80
128
|
NSString *markdown = markdownForRange(attributedText, range, cachedMarkdown);
|
|
81
129
|
NSArray<NSString *> *imageURLs = imageURLsInRange(attributedText, range);
|
|
130
|
+
// Same threshold markdownForRange uses to return the cached markdown.
|
|
131
|
+
BOOL fullSelection = range.location == 0 && range.length >= attributedText.length - 1;
|
|
82
132
|
|
|
83
|
-
UIAction *copyAction =
|
|
133
|
+
UIAction *copyAction =
|
|
134
|
+
createCopyAction(selectedText, markdown, fullSelection, styleConfig, selectionMenuConfig, onCopyRequest);
|
|
84
135
|
UIAction *copyMarkdownAction = selectionMenuConfig.copyAsMarkdown
|
|
85
136
|
? createCopyMarkdownAction(markdown, selectionMenuConfig.copyAsMarkdownLabel)
|
|
86
137
|
: nil;
|
|
@@ -88,6 +139,16 @@ UIMenu *buildEditMenuForSelection(NSAttributedString *attributedText, NSRange ra
|
|
|
88
139
|
selectionMenuConfig.copyImageURL ? createCopyImageURLAction(imageURLs, selectionMenuConfig) : nil;
|
|
89
140
|
|
|
90
141
|
NSMutableArray<UIMenuElement *> *result = [NSMutableArray array];
|
|
142
|
+
|
|
143
|
+
if (selectionMenuConfig.systemItemsNone) {
|
|
144
|
+
// Skip suggestedActions entirely. An empty result still yields an (empty)
|
|
145
|
+
// menu: returning nil would make UIKit present its default menu.
|
|
146
|
+
addOptionalAction(result, copyAction);
|
|
147
|
+
addOptionalAction(result, copyMarkdownAction);
|
|
148
|
+
addOptionalAction(result, copyImageURLAction);
|
|
149
|
+
return [UIMenu menuWithChildren:[(customActions ?: @[]) arrayByAddingObjectsFromArray:result]];
|
|
150
|
+
}
|
|
151
|
+
|
|
91
152
|
BOOL foundStandardEditMenu = NO;
|
|
92
153
|
|
|
93
154
|
for (UIMenuElement *element in suggestedActions) {
|
|
@@ -107,8 +168,8 @@ UIMenu *buildEditMenuForSelection(NSAttributedString *attributedText, NSRange ra
|
|
|
107
168
|
}
|
|
108
169
|
|
|
109
170
|
if (!foundStandardEditMenu) {
|
|
110
|
-
|
|
111
|
-
insertOptionalAction(result,
|
|
171
|
+
insertOptionalAction(result, copyMarkdownAction, 0);
|
|
172
|
+
insertOptionalAction(result, copyAction, 0);
|
|
112
173
|
addOptionalAction(result, copyImageURLAction);
|
|
113
174
|
}
|
|
114
175
|
|
|
@@ -119,4 +180,120 @@ UIMenu *buildEditMenuForSelection(NSAttributedString *attributedText, NSRange ra
|
|
|
119
180
|
return [UIMenu menuWithChildren:result];
|
|
120
181
|
}
|
|
121
182
|
|
|
183
|
+
#import <objc/runtime.h>
|
|
184
|
+
|
|
185
|
+
static const void *kSelectionEditMenuPresenterKey = &kSelectionEditMenuPresenterKey;
|
|
186
|
+
|
|
187
|
+
API_AVAILABLE(ios(16.0))
|
|
188
|
+
@interface ENRMSelectionEditMenuPresenter : NSObject <UIEditMenuInteractionDelegate>
|
|
189
|
+
@property (nonatomic, weak) UITextView *textView;
|
|
190
|
+
@property (nonatomic, strong) UIEditMenuInteraction *interaction;
|
|
191
|
+
@property (nonatomic, assign) NSRange range;
|
|
192
|
+
@end
|
|
193
|
+
|
|
194
|
+
@implementation ENRMSelectionEditMenuPresenter
|
|
195
|
+
|
|
196
|
+
- (UIMenu *)editMenuInteraction:(UIEditMenuInteraction *)interaction
|
|
197
|
+
menuForConfiguration:(UIEditMenuConfiguration *)configuration
|
|
198
|
+
suggestedActions:(NSArray<UIMenuElement *> *)suggestedActions
|
|
199
|
+
{
|
|
200
|
+
UITextView *textView = self.textView;
|
|
201
|
+
id<UITextViewDelegate> delegate = textView.delegate;
|
|
202
|
+
if (!textView || ![delegate respondsToSelector:@selector(textView:editMenuForTextInRange:suggestedActions:)]) {
|
|
203
|
+
return nil;
|
|
204
|
+
}
|
|
205
|
+
return [delegate textView:textView editMenuForTextInRange:textView.selectedRange suggestedActions:suggestedActions];
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
- (CGRect)editMenuInteraction:(UIEditMenuInteraction *)interaction
|
|
209
|
+
targetRectForConfiguration:(UIEditMenuConfiguration *)configuration
|
|
210
|
+
{
|
|
211
|
+
UITextView *textView = self.textView;
|
|
212
|
+
UITextRange *textRange = textView.selectedTextRange;
|
|
213
|
+
if (!textView || !textRange) {
|
|
214
|
+
return CGRectNull;
|
|
215
|
+
}
|
|
216
|
+
return [textView firstRectForRange:textRange];
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
@end
|
|
220
|
+
|
|
221
|
+
static BOOL selectionEditMenuTextViewHasActiveGesture(UITextView *textView)
|
|
222
|
+
{
|
|
223
|
+
for (UIGestureRecognizer *recognizer in textView.gestureRecognizers) {
|
|
224
|
+
if (recognizer.state == UIGestureRecognizerStateBegan || recognizer.state == UIGestureRecognizerStateChanged) {
|
|
225
|
+
return YES;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return NO;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
static void presentSelectionEditMenu(UITextView *textView)
|
|
232
|
+
{
|
|
233
|
+
UITextRange *textRange = textView.selectedTextRange;
|
|
234
|
+
if (!textRange || textRange.isEmpty) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
CGRect rect = [textView firstRectForRange:textRange];
|
|
238
|
+
if (CGRectIsNull(rect) || CGRectIsEmpty(rect)) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (@available(iOS 16.0, *)) {
|
|
242
|
+
ENRMSelectionEditMenuPresenter *presenter = objc_getAssociatedObject(textView, kSelectionEditMenuPresenterKey);
|
|
243
|
+
if (!presenter) {
|
|
244
|
+
presenter = [[ENRMSelectionEditMenuPresenter alloc] init];
|
|
245
|
+
presenter.textView = textView;
|
|
246
|
+
presenter.interaction = [[UIEditMenuInteraction alloc] initWithDelegate:presenter];
|
|
247
|
+
[textView addInteraction:presenter.interaction];
|
|
248
|
+
objc_setAssociatedObject(textView, kSelectionEditMenuPresenterKey, presenter, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
249
|
+
}
|
|
250
|
+
presenter.range = textView.selectedRange;
|
|
251
|
+
UIEditMenuConfiguration *configuration =
|
|
252
|
+
[UIEditMenuConfiguration configurationWithIdentifier:nil
|
|
253
|
+
sourcePoint:CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect))];
|
|
254
|
+
[presenter.interaction presentEditMenuWithConfiguration:configuration];
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
#pragma clang diagnostic push
|
|
258
|
+
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
259
|
+
[[UIMenuController sharedMenuController] showMenuFromView:textView rect:rect];
|
|
260
|
+
#pragma clang diagnostic pop
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
static void presentSelectionEditMenuWhenTouchEnds(UITextView *textView, NSRange range, NSUInteger attemptsLeft)
|
|
264
|
+
{
|
|
265
|
+
if (!NSEqualRanges(textView.selectedRange, range)) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (attemptsLeft > 0 && selectionEditMenuTextViewHasActiveGesture(textView)) {
|
|
269
|
+
__weak UITextView *weakTextView = textView;
|
|
270
|
+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(50 * NSEC_PER_MSEC)), dispatch_get_main_queue(), ^{
|
|
271
|
+
UITextView *strongTextView = weakTextView;
|
|
272
|
+
if (strongTextView) {
|
|
273
|
+
presentSelectionEditMenuWhenTouchEnds(strongTextView, range, attemptsLeft - 1);
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
presentSelectionEditMenu(textView);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
void ENRMSelectRangeAndPresentEditMenu(UITextView *textView, NSRange range)
|
|
282
|
+
{
|
|
283
|
+
[textView becomeFirstResponder];
|
|
284
|
+
textView.selectedRange = range;
|
|
285
|
+
presentSelectionEditMenuWhenTouchEnds(textView, range, 200);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
void ENRMDismissSelectionEditMenuIfMoved(UITextView *textView)
|
|
289
|
+
{
|
|
290
|
+
if (@available(iOS 16.0, *)) {
|
|
291
|
+
ENRMSelectionEditMenuPresenter *presenter = objc_getAssociatedObject(textView, kSelectionEditMenuPresenterKey);
|
|
292
|
+
if (presenter && !NSEqualRanges(textView.selectedRange, presenter.range)) {
|
|
293
|
+
presenter.range = NSMakeRange(NSNotFound, 0);
|
|
294
|
+
[presenter.interaction dismissMenu];
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
122
299
|
#endif
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
#import "CodeBackground.h"
|
|
4
4
|
#import "ENRMFeatureFlags.h"
|
|
5
5
|
#import "ENRMImageAttachment.h"
|
|
6
|
+
#import "ENRMLinkChip.h"
|
|
6
7
|
#import "HighlightRenderer.h"
|
|
7
8
|
#if ENRICHED_MARKDOWN_MATH
|
|
8
9
|
#import "ENRMMathInlineAttachment.h"
|
|
@@ -460,7 +461,7 @@ static void generateInlineHTML(NSMutableString *html, NSAttributedString *attrib
|
|
|
460
461
|
usingBlock:^(NSDictionary<NSAttributedStringKey, id> *attrs, NSRange attrRange, BOOL *stop) {
|
|
461
462
|
NSString *text = [string substringWithRange:attrRange];
|
|
462
463
|
|
|
463
|
-
if ([text isEqualToString:@"\n"])
|
|
464
|
+
if ([text isEqualToString:@"\n"] || attrs[ENRMLinkSpacerAttributeName])
|
|
464
465
|
return;
|
|
465
466
|
|
|
466
467
|
if ([text containsString:kObjectReplacementChar]) {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#import <Foundation/Foundation.h>
|
|
4
|
+
|
|
5
|
+
#ifdef __cplusplus
|
|
6
|
+
#include <vector>
|
|
7
|
+
|
|
8
|
+
template <typename T>
|
|
9
|
+
static bool ENRMImageRequestHeadersChanged(const std::vector<T> &oldHeaders, const std::vector<T> &newHeaders)
|
|
10
|
+
{
|
|
11
|
+
if (newHeaders.size() != oldHeaders.size()) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
for (size_t i = 0; i < newHeaders.size(); i++) {
|
|
15
|
+
if (newHeaders[i].name != oldHeaders[i].name || newHeaders[i].value != oldHeaders[i].value) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
template <typename T>
|
|
23
|
+
static NSDictionary<NSString *, NSString *> *_Nullable ENRMImageRequestHeadersFromProps(const std::vector<T> &headers)
|
|
24
|
+
{
|
|
25
|
+
if (headers.empty()) {
|
|
26
|
+
return nil;
|
|
27
|
+
}
|
|
28
|
+
NSMutableDictionary<NSString *, NSString *> *result = [NSMutableDictionary dictionaryWithCapacity:headers.size()];
|
|
29
|
+
for (const auto &header : headers) {
|
|
30
|
+
result[@(header.name.c_str())] = @(header.value.c_str());
|
|
31
|
+
}
|
|
32
|
+
return [result copy];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
#endif
|
|
@@ -5,11 +5,7 @@
|
|
|
5
5
|
#import "RenderContext.h"
|
|
6
6
|
#import "StyleConfig.h"
|
|
7
7
|
|
|
8
|
-
extern NSString *const
|
|
9
|
-
extern NSString *const ListTypeAttribute;
|
|
10
|
-
extern NSString *const ListItemNumberAttribute;
|
|
11
|
-
extern NSString *const TaskItemAttribute;
|
|
12
|
-
extern NSString *const TaskCheckedAttribute;
|
|
8
|
+
extern NSString *const ListItemMarkerStartAttribute;
|
|
13
9
|
|
|
14
10
|
@implementation ListMarkerDrawer {
|
|
15
11
|
StyleConfig *_config;
|
|
@@ -44,13 +40,13 @@ extern NSString *const TaskCheckedAttribute;
|
|
|
44
40
|
if (charRange.location == NSNotFound)
|
|
45
41
|
return;
|
|
46
42
|
|
|
47
|
-
// 1. Fetch all attributes at once for efficiency
|
|
48
43
|
NSDictionary *attrs = [storage attributesAtIndex:charRange.location
|
|
49
44
|
effectiveRange:NULL];
|
|
50
|
-
|
|
45
|
+
NSArray *markers = attrs[ListItemMarkerStartAttribute];
|
|
46
|
+
if (![markers isKindOfClass:[NSArray class]] || markers.count == 0)
|
|
51
47
|
return;
|
|
52
48
|
|
|
53
|
-
//
|
|
49
|
+
// Identify the start of the paragraph
|
|
54
50
|
NSRange paraRange = [storage.string paragraphRangeForRange:charRange];
|
|
55
51
|
if (charRange.location != paraRange.location ||
|
|
56
52
|
[drawnParagraphs containsObject:@(paraRange.location)])
|
|
@@ -61,30 +57,28 @@ extern NSString *const TaskCheckedAttribute;
|
|
|
61
57
|
|
|
62
58
|
CGPoint glyphLoc = [layoutManager locationForGlyphAtIndex:glyphRange.location];
|
|
63
59
|
CGFloat baselineY = origin.y + rect.origin.y + glyphLoc.y;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
centerY:baselineY - (font.capHeight /
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
} else {
|
|
87
|
-
[self drawOrderedMarkerAtX:markerX attrs:attrs baselineY:baselineY isRTL:isRTL];
|
|
60
|
+
UIFont *font = attrs[NSFontAttributeName] ?: [self defaultFont];
|
|
61
|
+
|
|
62
|
+
for (ENRMListMarkerDescriptor *marker in markers) {
|
|
63
|
+
CGFloat markerX = isRTL ? origin.x + container.size.width - marker.indent + gap
|
|
64
|
+
: origin.x + marker.indent - gap;
|
|
65
|
+
|
|
66
|
+
if (marker.isTask) {
|
|
67
|
+
const CGFloat size = [_config taskListCheckboxSize];
|
|
68
|
+
CGFloat checkboxX = isRTL ? markerX + size / 2.0 : markerX - size / 2.0;
|
|
69
|
+
[self drawCheckboxAtX:checkboxX
|
|
70
|
+
centerY:baselineY - (font.capHeight / 2.0)
|
|
71
|
+
checked:marker.isChecked];
|
|
72
|
+
} else if (marker.listType == ListTypeUnordered) {
|
|
73
|
+
[self drawBulletAtX:markerX
|
|
74
|
+
centerY:baselineY - (font.xHeight + font.capHeight) / 4.0
|
|
75
|
+
depth:marker.depth];
|
|
76
|
+
} else {
|
|
77
|
+
[self drawOrderedMarkerAtX:markerX
|
|
78
|
+
number:marker.number
|
|
79
|
+
baselineY:baselineY
|
|
80
|
+
isRTL:isRTL];
|
|
81
|
+
}
|
|
88
82
|
}
|
|
89
83
|
}];
|
|
90
84
|
}
|
|
@@ -167,17 +161,10 @@ extern NSString *const TaskCheckedAttribute;
|
|
|
167
161
|
y:y];
|
|
168
162
|
}
|
|
169
163
|
|
|
170
|
-
- (void)drawOrderedMarkerAtX:(CGFloat)boundaryX
|
|
171
|
-
attrs:(NSDictionary *)attrs
|
|
172
|
-
baselineY:(CGFloat)baselineY
|
|
173
|
-
isRTL:(BOOL)isRTL
|
|
164
|
+
- (void)drawOrderedMarkerAtX:(CGFloat)boundaryX number:(NSInteger)number baselineY:(CGFloat)baselineY isRTL:(BOOL)isRTL
|
|
174
165
|
{
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
return;
|
|
178
|
-
|
|
179
|
-
NSString *text = isRTL ? [NSString stringWithFormat:@".%ld", (long)num.integerValue]
|
|
180
|
-
: [NSString stringWithFormat:@"%ld.", (long)num.integerValue];
|
|
166
|
+
NSString *text =
|
|
167
|
+
isRTL ? [NSString stringWithFormat:@".%ld", (long)number] : [NSString stringWithFormat:@"%ld.", (long)number];
|
|
181
168
|
UIFont *font = [_config listMarkerFont] ?: [self defaultFont];
|
|
182
169
|
|
|
183
170
|
NSDictionary *mAttrs = @{NSFontAttributeName : font, NSForegroundColorAttributeName : [_config listStyleMarkerColor]};
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
#import "AccessibilityInfo.h"
|
|
3
3
|
#import "BlockquoteBorder.h"
|
|
4
4
|
#import "ENRMAccessibilityLabels.h"
|
|
5
|
+
#import "ENRMLinkChip.h"
|
|
5
6
|
#include <TargetConditionals.h>
|
|
6
7
|
|
|
7
8
|
typedef NS_ENUM(NSInteger, ElementType) { ElementTypeText, ElementTypeLink, ElementTypeImage };
|
|
@@ -113,7 +114,8 @@ static const CGFloat kFocusRectPadding = 2.0;
|
|
|
113
114
|
}
|
|
114
115
|
|
|
115
116
|
BOOL isImg = item[@"altText"] != nil;
|
|
116
|
-
|
|
117
|
+
// Link chips pad their text with spacer characters; keep them out of the spoken label.
|
|
118
|
+
NSString *label = isImg ? item[@"altText"] : ENRMPlainTextByRemovingLinkSpacers(textView.attributedText, itemRange);
|
|
117
119
|
[elements addObject:[self createElementForRange:itemRange
|
|
118
120
|
type:isImg ? ElementTypeImage : ElementTypeLink
|
|
119
121
|
text:label
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
#import "BlockquoteBorder.h"
|
|
3
3
|
#import "ENRMFeatureFlags.h"
|
|
4
4
|
#import "ENRMImageAttachment.h"
|
|
5
|
+
#import "ENRMLinkChip.h"
|
|
5
6
|
#import "ENRMUIKit.h"
|
|
6
7
|
#import "HighlightRenderer.h"
|
|
7
8
|
#include <TargetConditionals.h>
|
|
@@ -152,7 +153,7 @@ NSString *_Nullable extractMarkdownFromAttributedString(NSAttributedString *attr
|
|
|
152
153
|
options:0
|
|
153
154
|
usingBlock:^(NSDictionary<NSAttributedStringKey, id> *attrs, NSRange attrRange, BOOL *stop) {
|
|
154
155
|
NSString *text = [[attributedText attributedSubstringFromRange:attrRange] string];
|
|
155
|
-
if (text.length == 0)
|
|
156
|
+
if (text.length == 0 || attrs[ENRMLinkSpacerAttributeName])
|
|
156
157
|
return;
|
|
157
158
|
|
|
158
159
|
// Images and Thematic Breaks
|
|
@@ -45,6 +45,11 @@ NSUInteger applyBlockSpacingBefore(NSMutableAttributedString *output, NSUInteger
|
|
|
45
45
|
void applyBlockSpacingAfter(NSMutableAttributedString *output, CGFloat marginBottom);
|
|
46
46
|
void applyLineHeight(NSMutableAttributedString *output, NSRange range, CGFloat lineHeight);
|
|
47
47
|
void applyBaselineOffset(NSMutableAttributedString *output, NSRange range);
|
|
48
|
+
|
|
49
|
+
/// True when the range contains a block (non-inline) image attachment. Lines holding
|
|
50
|
+
/// such attachments must not be clamped by maximumLineHeight or the image box
|
|
51
|
+
/// overflows the line and paints over surrounding content.
|
|
52
|
+
BOOL ENRMRangeContainsBlockImage(NSAttributedString *output, NSRange range);
|
|
48
53
|
void applyTextAlignment(NSMutableAttributedString *output, NSRange range, NSTextAlignment textAlign);
|
|
49
54
|
NSTextAlignment textAlignmentFromString(NSString *textAlign);
|
|
50
55
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#import "ParagraphStyleUtils.h"
|
|
2
2
|
#import "ENRMFeatureFlags.h"
|
|
3
|
+
#import "ENRMImageAttachment.h"
|
|
3
4
|
#import "LastElementUtils.h"
|
|
4
5
|
#import <React/RCTI18nUtil.h>
|
|
5
6
|
|
|
@@ -246,6 +247,21 @@ void applyBlockSpacingAfter(NSMutableAttributedString *output, CGFloat marginBot
|
|
|
246
247
|
[output addAttribute:NSParagraphStyleAttributeName value:spacerStyle range:NSMakeRange(spacerLocation, 1)];
|
|
247
248
|
}
|
|
248
249
|
|
|
250
|
+
BOOL ENRMRangeContainsBlockImage(NSAttributedString *output, NSRange range)
|
|
251
|
+
{
|
|
252
|
+
__block BOOL found = NO;
|
|
253
|
+
[output enumerateAttribute:NSAttachmentAttributeName
|
|
254
|
+
inRange:range
|
|
255
|
+
options:0
|
|
256
|
+
usingBlock:^(id value, __unused NSRange attrRange, BOOL *stop) {
|
|
257
|
+
if ([value isKindOfClass:[ENRMImageAttachment class]] && !((ENRMImageAttachment *)value).isInline) {
|
|
258
|
+
found = YES;
|
|
259
|
+
*stop = YES;
|
|
260
|
+
}
|
|
261
|
+
}];
|
|
262
|
+
return found;
|
|
263
|
+
}
|
|
264
|
+
|
|
249
265
|
void applyLineHeight(NSMutableAttributedString *output, NSRange range, CGFloat lineHeight)
|
|
250
266
|
{
|
|
251
267
|
if (lineHeight <= 0) {
|
|
@@ -266,10 +282,12 @@ void applyLineHeight(NSMutableAttributedString *output, NSRange range, CGFloat l
|
|
|
266
282
|
}];
|
|
267
283
|
#endif
|
|
268
284
|
|
|
285
|
+
BOOL hasBlockImage = ENRMRangeContainsBlockImage(output, range);
|
|
286
|
+
|
|
269
287
|
NSMutableParagraphStyle *style = getOrCreateParagraphStyle(output, range.location);
|
|
270
288
|
|
|
271
289
|
style.minimumLineHeight = lineHeight;
|
|
272
|
-
style.maximumLineHeight = hasMath ? 0 : lineHeight;
|
|
290
|
+
style.maximumLineHeight = (hasMath || hasBlockImage) ? 0 : lineHeight;
|
|
273
291
|
|
|
274
292
|
[output addAttribute:NSParagraphStyleAttributeName value:style range:range];
|
|
275
293
|
}
|
|
@@ -284,7 +302,8 @@ void applyBaselineOffset(NSMutableAttributedString *output, NSRange range)
|
|
|
284
302
|
return;
|
|
285
303
|
}
|
|
286
304
|
|
|
287
|
-
|
|
305
|
+
// Math paragraphs leave maximumLineHeight at 0, so fall back to minimumLineHeight.
|
|
306
|
+
__block CGFloat targetLineHeight = 0;
|
|
288
307
|
[output enumerateAttribute:NSParagraphStyleAttributeName
|
|
289
308
|
inRange:range
|
|
290
309
|
options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
|
|
@@ -292,29 +311,59 @@ void applyBaselineOffset(NSMutableAttributedString *output, NSRange range)
|
|
|
292
311
|
if (!paragraphStyle) {
|
|
293
312
|
return;
|
|
294
313
|
}
|
|
295
|
-
|
|
314
|
+
CGFloat clamp = MAX(paragraphStyle.maximumLineHeight, paragraphStyle.minimumLineHeight);
|
|
315
|
+
targetLineHeight = MAX(clamp, targetLineHeight);
|
|
296
316
|
}];
|
|
297
317
|
|
|
298
|
-
if (
|
|
318
|
+
if (targetLineHeight <= 0) {
|
|
299
319
|
return;
|
|
300
320
|
}
|
|
301
321
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
322
|
+
// Center on real text; on a math-only line center the math box instead of its font.
|
|
323
|
+
__block CGFloat textLineHeight = 0;
|
|
324
|
+
#if ENRICHED_MARKDOWN_MATH
|
|
325
|
+
__block BOOL hasMath = NO;
|
|
326
|
+
#endif
|
|
327
|
+
[output enumerateAttributesInRange:range
|
|
328
|
+
options:0
|
|
329
|
+
usingBlock:^(NSDictionary<NSAttributedStringKey, id> *attrs, __unused NSRange subrange,
|
|
330
|
+
__unused BOOL *stop) {
|
|
331
|
+
#if ENRICHED_MARKDOWN_MATH
|
|
332
|
+
if ([attrs[NSAttachmentAttributeName] isKindOfClass:[ENRMMathInlineAttachment class]]) {
|
|
333
|
+
hasMath = YES;
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
#endif
|
|
337
|
+
UIFont *font = attrs[NSFontAttributeName];
|
|
338
|
+
if (font) {
|
|
339
|
+
textLineHeight = MAX(UIFontLineHeight(font), textLineHeight);
|
|
340
|
+
}
|
|
341
|
+
}];
|
|
342
|
+
|
|
343
|
+
CGFloat contentLineHeight = textLineHeight;
|
|
344
|
+
|
|
345
|
+
#if ENRICHED_MARKDOWN_MATH
|
|
346
|
+
// Math only grows the content height, so measure it (parsing LaTeX) only when text
|
|
347
|
+
// alone wouldn't already fill the line.
|
|
348
|
+
if (hasMath && targetLineHeight > textLineHeight) {
|
|
349
|
+
__block CGFloat mathBoxHeight = 0;
|
|
350
|
+
[output enumerateAttribute:NSAttachmentAttributeName
|
|
351
|
+
inRange:range
|
|
352
|
+
options:0
|
|
353
|
+
usingBlock:^(id value, __unused NSRange subrange, __unused BOOL *stop) {
|
|
354
|
+
if ([value isKindOfClass:[ENRMMathInlineAttachment class]]) {
|
|
355
|
+
mathBoxHeight = MAX(((ENRMMathInlineAttachment *)value).boxHeight, mathBoxHeight);
|
|
356
|
+
}
|
|
357
|
+
}];
|
|
358
|
+
contentLineHeight = MAX(textLineHeight, mathBoxHeight);
|
|
359
|
+
}
|
|
360
|
+
#endif
|
|
312
361
|
|
|
313
|
-
if (
|
|
362
|
+
if (contentLineHeight <= 0 || targetLineHeight <= contentLineHeight) {
|
|
314
363
|
return;
|
|
315
364
|
}
|
|
316
365
|
|
|
317
|
-
CGFloat baseLineOffset = (
|
|
366
|
+
CGFloat baseLineOffset = (targetLineHeight - contentLineHeight) / 2.0;
|
|
318
367
|
|
|
319
368
|
[output enumerateAttribute:NSBaselineOffsetAttributeName
|
|
320
369
|
inRange:range
|
|
@@ -323,7 +372,18 @@ void applyBaselineOffset(NSMutableAttributedString *output, NSRange range)
|
|
|
323
372
|
if (existingOffset != nil) {
|
|
324
373
|
return;
|
|
325
374
|
}
|
|
326
|
-
[output
|
|
375
|
+
[output enumerateAttribute:NSAttachmentAttributeName
|
|
376
|
+
inRange:subrange
|
|
377
|
+
options:0
|
|
378
|
+
usingBlock:^(id attachment, NSRange attachmentRange, BOOL *innerStop) {
|
|
379
|
+
if ([attachment isKindOfClass:[ENRMImageAttachment class]] &&
|
|
380
|
+
!((ENRMImageAttachment *)attachment).isInline) {
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
[output addAttribute:NSBaselineOffsetAttributeName
|
|
384
|
+
value:@(baseLineOffset)
|
|
385
|
+
range:attachmentRange];
|
|
386
|
+
}];
|
|
327
387
|
}];
|
|
328
388
|
}
|
|
329
389
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#import "RTFExportUtils.h"
|
|
2
2
|
#import "BlockquoteBorder.h"
|
|
3
3
|
#import "CodeBackground.h"
|
|
4
|
+
#import "ENRMLinkChip.h"
|
|
4
5
|
#import "LastElementUtils.h"
|
|
5
6
|
#import "ListItemRenderer.h"
|
|
6
7
|
#import "RenderContext.h"
|
|
@@ -288,6 +289,7 @@ NSAttributedString *prepareAttributedStringForRTFExport(NSAttributedString *attr
|
|
|
288
289
|
RCTUIColor *blockquoteBgColor = [styleConfig blockquoteBackgroundColor];
|
|
289
290
|
|
|
290
291
|
processThematicBreaks(prepared);
|
|
292
|
+
ENRMApplyLinkChipBackgroundsAsTextBackground(prepared);
|
|
291
293
|
processCodes(prepared, codeBgColor);
|
|
292
294
|
processCodeBlocks(prepared, codeBlockBgColor);
|
|
293
295
|
processBlockquotes(prepared, blockquoteBgColor);
|