react-native-enriched-markdown-scaffold 0.7.4-scaffold.8 → 1.0.2-scaffold.1
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 +191 -1
- package/android/consumer-rules.pro +1 -1
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +9 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +3 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerDelegate.java +27 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerInterface.java +9 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +9 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +3 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +40 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +839 -23
- package/android/src/main/baseline-prof.txt +1 -1
- package/android/src/main/cpp/jni-adapter.cpp +74 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +175 -11
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +50 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +48 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextLayoutManager.kt +10 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +42 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +82 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/events/CopyPressEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputManager.kt +62 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +911 -460
- package/android/src/main/java/com/swmansion/enriched/markdown/input/MarkdownClipboard.kt +42 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/BlockEditCoordinator.kt +196 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/ClipboardCoordinator.kt +73 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditContext.kt +19 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditPipeline.kt +248 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditSession.kt +52 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/InputConnectionWrapper.kt +101 -7
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/LinkCoordinator.kt +69 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MarkdownTextWatcher.kt +3 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MentionCoordinator.kt +118 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeStateEvent.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnContextMenuItemPressEvent.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnInputKeyPressEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnPasteEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockStore.kt +254 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockSyntaxSentinel.kt +69 -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 +180 -27
- 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 +7 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockRange.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockType.kt +48 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/FormattingRange.kt +9 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/InputFormatterStyle.kt +39 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathAtom.kt +20 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MutableRangeBounds.kt +11 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputBulletSpan.kt +82 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputHeadingSpan.kt +58 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputListItemSpacingSpan.kt +37 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputOrderedListMarkerSpan.kt +63 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/BlockHandler.kt +54 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/HeadingBlockHandler.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/OrderedListBlockHandler.kt +38 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/UnorderedListBlockHandler.kt +37 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +8 -26
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +9 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +100 -12
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +16 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +2 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +74 -18
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +43 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +9 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SoftBreakRenderer.kt +16 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +30 -27
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +174 -24
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +27 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +13 -16
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +182 -46
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListItemSpacingSpan.kt +33 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListMarkerAnchorSpan.kt +38 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +2 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +3 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +3 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +7 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +4 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +13 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockHighlighter.kt +90 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockNode.kt +57 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/FeatureFlags.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownSegment.kt +9 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +33 -7
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/ReadableMapExtensions.kt +3 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/RenderedSegment.kt +10 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentSignature.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/StreamingMarkdownFilter.kt +83 -5
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +74 -44
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/PasteTextUtils.kt +20 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +26 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +22 -9
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/LocalImageLoader.kt +161 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/TextPaintExtensions.kt +23 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/CheckboxTouchHelper.kt +7 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +41 -21
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt +15 -8
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLongPressMovementMethod.kt +58 -27
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +19 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +388 -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 +32 -5
- package/android/src/main/jni/CMakeLists.txt +53 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.cpp +10 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +11 -2
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +10 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +12 -2
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.cpp +9 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.h +24 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +16 -0
- package/android/src/math/java/com/swmansion/enriched/markdown/input/math/MathChipControllerImpl.kt +21 -4
- package/android/src/math/java/com/swmansion/enriched/markdown/renderer/MathInlineRenderer.kt +7 -2
- package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +1 -1
- package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +2 -0
- 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 +231 -8
- package/docs/BREAKING_CHANGES.md +129 -0
- package/docs/CODE_HIGHLIGHT.md +133 -0
- package/docs/COPY_OPTIONS.md +21 -3
- package/docs/ELEMENTS_STRUCTURE.md +52 -4
- package/docs/IMAGE_CACHING.md +30 -0
- package/docs/INPUT.md +146 -5
- package/docs/LATEX_MATH.md +87 -45
- package/docs/MACOS.md +1 -1
- package/docs/MARKDOWN_STREAMING.md +27 -1
- package/docs/NATIVE_ASSETS.md +127 -0
- package/docs/RTL.md +1 -1
- package/docs/STYLES.md +46 -6
- package/docs/TESTING.md +112 -0
- package/docs/TEXT.md +16 -6
- package/docs/WEB.md +3 -1
- package/ios/EnrichedMarkdown.h +7 -0
- package/ios/EnrichedMarkdown.mm +262 -67
- package/ios/EnrichedMarkdownText.h +7 -0
- package/ios/EnrichedMarkdownText.mm +97 -68
- package/ios/attachments/ENRMImageAttachment.h +9 -0
- package/ios/attachments/ENRMImageAttachment.m +143 -40
- package/ios/attachments/ENRMMathInlineAttachment.h +2 -0
- package/ios/attachments/ENRMMathInlineAttachment.m +48 -81
- package/ios/attachments/ENRMMathInlineAttachmentShared.h +2 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +40 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +839 -23
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +131 -0
- package/ios/input/ENRMAutoLinkDetector.h +2 -1
- package/ios/input/ENRMAutoLinkDetector.mm +79 -41
- package/ios/input/ENRMBlockEditCoordinator.h +71 -0
- package/ios/input/ENRMBlockEditCoordinator.mm +195 -0
- package/ios/input/ENRMBlockRange.h +28 -0
- package/ios/input/ENRMBlockRange.mm +30 -0
- package/ios/input/ENRMBlockStore.h +56 -0
- package/ios/input/ENRMBlockStore.mm +275 -0
- package/ios/input/ENRMBlockSyntaxSentinel.h +25 -0
- package/ios/input/ENRMBlockSyntaxSentinel.mm +80 -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 +10 -6
- package/ios/input/ENRMInputParser.mm +527 -171
- 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 +1104 -1024
- package/ios/input/InputStylePropsUtils.h +109 -68
- package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.mm +2 -1
- package/ios/input/styles/ENRMBlockHandler.h +46 -0
- package/ios/input/styles/ENRMHeadingBlockHandler.h +15 -0
- package/ios/input/styles/ENRMHeadingBlockHandler.mm +38 -0
- package/ios/input/styles/ENRMOrderedListBlockHandler.h +14 -0
- package/ios/input/styles/ENRMOrderedListBlockHandler.mm +48 -0
- package/ios/input/styles/ENRMUnorderedListBlockHandler.h +15 -0
- package/ios/input/styles/ENRMUnorderedListBlockHandler.mm +51 -0
- package/ios/internals/ENRMViewFreeMeasurement.h +331 -0
- package/ios/internals/EnrichedMarkdownShadowNode.h +1 -3
- package/ios/internals/EnrichedMarkdownShadowNode.mm +16 -20
- package/ios/internals/EnrichedMarkdownTextShadowNode.h +1 -3
- package/ios/internals/EnrichedMarkdownTextShadowNode.mm +15 -20
- package/ios/internals/MeasurementCache.h +33 -7
- package/ios/internals/ShadowMeasurementUtils.h +63 -58
- package/ios/math/ENRMMathChipController.h +74 -0
- package/ios/math/ENRMMathChipController.mm +476 -0
- package/ios/math/ENRMRaTeXBridge.swift +4 -1
- package/ios/parser/ENRMMarkdownParser.h +1 -8
- package/ios/parser/ENRMMarkdownParser.mm +2 -11
- package/ios/parser/MarkdownASTNode.h +2 -1
- package/ios/parser/MarkdownParserBridge.mm +4 -0
- package/ios/renderer/AttributedRenderer.m +20 -2
- package/ios/renderer/BaseRenderer.h +17 -2
- package/ios/renderer/BaseRenderer.m +30 -0
- package/ios/renderer/BlockquoteRenderer.h +1 -1
- package/ios/renderer/BlockquoteRenderer.m +144 -35
- package/ios/renderer/CodeBlockRenderer.h +1 -1
- package/ios/renderer/CodeBlockRenderer.m +27 -23
- package/ios/renderer/CodeRenderer.h +1 -1
- package/ios/renderer/CodeRenderer.m +3 -1
- package/ios/renderer/ENRMImageRenderer.h +1 -1
- package/ios/renderer/ENRMImageRenderer.m +5 -1
- package/ios/renderer/ENRMMathInlineRenderer.h +1 -1
- package/ios/renderer/ENRMMathInlineRenderer.m +5 -1
- package/ios/renderer/ENRMSpoilerRenderer.h +1 -1
- package/ios/renderer/ENRMSpoilerRenderer.m +3 -1
- package/ios/renderer/EmphasisRenderer.h +1 -1
- package/ios/renderer/EmphasisRenderer.m +3 -1
- package/ios/renderer/HeadingRenderer.h +1 -1
- package/ios/renderer/HeadingRenderer.m +13 -6
- package/ios/renderer/HighlightRenderer.h +1 -1
- package/ios/renderer/HighlightRenderer.m +3 -1
- package/ios/renderer/LinkRenderer.h +1 -1
- package/ios/renderer/LinkRenderer.m +3 -1
- package/ios/renderer/ListItemRenderer.h +13 -1
- package/ios/renderer/ListItemRenderer.m +102 -44
- package/ios/renderer/ListRenderer.h +2 -2
- package/ios/renderer/ListRenderer.m +63 -25
- package/ios/renderer/ParagraphRenderer.h +1 -1
- package/ios/renderer/ParagraphRenderer.m +16 -8
- package/ios/renderer/RenderContext.h +10 -0
- package/ios/renderer/RenderContext.m +44 -0
- package/ios/renderer/RendererFactory.m +14 -0
- package/ios/renderer/StrikethroughRenderer.h +1 -1
- package/ios/renderer/StrikethroughRenderer.m +3 -1
- package/ios/renderer/StrongRenderer.h +1 -1
- package/ios/renderer/StrongRenderer.m +3 -1
- package/ios/renderer/SubscriptRenderer.h +1 -1
- package/ios/renderer/SubscriptRenderer.m +3 -1
- package/ios/renderer/SuperscriptRenderer.h +1 -1
- package/ios/renderer/SuperscriptRenderer.m +3 -1
- package/ios/renderer/TextRenderer.h +2 -2
- package/ios/renderer/TextRenderer.m +3 -1
- package/ios/renderer/ThematicBreakRenderer.h +1 -1
- package/ios/renderer/ThematicBreakRenderer.m +3 -1
- package/ios/renderer/UnderlineRenderer.h +1 -1
- package/ios/renderer/UnderlineRenderer.m +3 -1
- package/ios/styles/StyleConfig.h +22 -0
- package/ios/styles/StyleConfig.mm +132 -0
- package/ios/utils/BlockquoteBorder.h +6 -0
- package/ios/utils/BlockquoteBorder.m +249 -52
- package/ios/utils/CodeBlockBackground.m +16 -2
- package/ios/utils/ENRMAtomicSize.h +65 -0
- package/ios/utils/ENRMCodeBlockContent.h +37 -0
- package/ios/utils/ENRMCodeBlockContent.mm +79 -0
- package/ios/utils/ENRMCodeBlockHighlighter.h +37 -0
- package/ios/utils/ENRMCodeBlockHighlighter.mm +51 -0
- package/ios/utils/ENRMFeatureFlags.h +7 -0
- package/ios/utils/ENRMImageDownloader.h +11 -1
- package/ios/utils/ENRMImageDownloader.m +60 -16
- package/ios/utils/ENRMLocalImageLoader.h +31 -0
- package/ios/utils/ENRMLocalImageLoader.m +68 -0
- package/ios/utils/ENRMMathFallback.h +26 -0
- package/ios/utils/ENRMMathFallback.m +18 -0
- package/ios/utils/ENRMTextViewSetup.h +35 -17
- package/ios/utils/EditMenuUtils.m +22 -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/ParagraphStyleUtils.h +5 -0
- package/ios/utils/ParagraphStyleUtils.m +77 -17
- package/ios/utils/RenderedMarkdownSegment.h +13 -1
- package/ios/utils/RenderedMarkdownSegment.m +20 -0
- package/ios/utils/SegmentRenderer.m +17 -4
- package/ios/utils/StreamingMarkdownFilter.h +11 -1
- package/ios/utils/StreamingMarkdownFilter.m +98 -2
- package/ios/utils/StylePropsUtils.h +63 -0
- package/ios/utils/TaskListTapUtils.m +24 -0
- package/ios/views/ENRMCodeBlockContainerView.h +46 -0
- package/ios/views/ENRMCodeBlockContainerView.m +566 -0
- package/ios/views/ENRMMathContainerView.h +12 -0
- package/ios/views/ENRMMathContainerView.m +71 -1
- package/ios/views/TableContainerView.h +18 -0
- package/ios/views/TableContainerView.m +259 -159
- package/jest.d.ts +1 -0
- package/jest.js +5 -0
- package/lib/module/EnrichedMarkdownNativeComponent.ts +65 -0
- package/lib/module/EnrichedMarkdownTextInput.js +86 -5
- package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
- package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +89 -5
- package/lib/module/EnrichedMarkdownTextNativeComponent.ts +66 -0
- package/lib/module/headingDefaults.js +34 -0
- package/lib/module/headingDefaults.js.map +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/jest/index.js +191 -0
- package/lib/module/jest/index.js.map +1 -0
- package/lib/module/native/EnrichedMarkdownText.js +30 -4
- package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
- package/lib/module/normalizeMarkdownStyle.js +81 -19
- package/lib/module/normalizeMarkdownStyle.js.map +1 -1
- package/lib/module/normalizeMarkdownStyle.web.js +56 -18
- package/lib/module/normalizeMarkdownStyle.web.js.map +1 -1
- package/lib/module/normalizeMarkdownTextInputStyle.js +62 -15
- package/lib/module/normalizeMarkdownTextInputStyle.js.map +1 -1
- package/lib/module/normalizeMenuItem.js +1 -1
- package/lib/module/utils/textInputState.js +26 -0
- package/lib/module/utils/textInputState.js.map +1 -0
- package/lib/module/web/EnrichedMarkdownText.js +9 -5
- package/lib/module/web/EnrichedMarkdownText.js.map +1 -1
- package/lib/module/web/parseMarkdown.js +4 -3
- package/lib/module/web/parseMarkdown.js.map +1 -1
- package/lib/module/web/renderers/InlineRenderers.js +6 -0
- package/lib/module/web/renderers/InlineRenderers.js.map +1 -1
- package/lib/module/web/renderers/ListRenderers.js +7 -2
- package/lib/module/web/renderers/ListRenderers.js.map +1 -1
- package/lib/module/web/renderers/index.js +7 -4
- package/lib/module/web/renderers/index.js.map +1 -1
- package/lib/module/web/styles.js +83 -6
- package/lib/module/web/styles.js.map +1 -1
- package/lib/module/web/utils.js +1 -0
- package/lib/module/web/utils.js.map +1 -1
- package/lib/module/web/wasm/md4c.js +0 -0
- package/lib/module/web/wasm/md4c.js.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +62 -0
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +95 -9
- package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +80 -5
- package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +62 -0
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/headingDefaults.d.ts +9 -0
- package/lib/typescript/src/headingDefaults.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +2 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/index.web.d.ts +1 -1
- package/lib/typescript/src/index.web.d.ts.map +1 -1
- package/lib/typescript/src/jest/index.d.ts +6 -0
- package/lib/typescript/src/jest/index.d.ts.map +1 -0
- package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +3 -3
- package/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts +19 -5
- package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownStyle.d.ts +72 -0
- package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +27 -0
- package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownTextProps.d.ts +65 -1
- package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownTextProps.web.d.ts +19 -0
- package/lib/typescript/src/types/MarkdownTextProps.web.d.ts.map +1 -1
- package/lib/typescript/src/types/events.d.ts +19 -0
- package/lib/typescript/src/types/events.d.ts.map +1 -1
- package/lib/typescript/src/utils/textInputState.d.ts +24 -0
- package/lib/typescript/src/utils/textInputState.d.ts.map +1 -0
- package/lib/typescript/src/web/EnrichedMarkdownText.d.ts +1 -1
- package/lib/typescript/src/web/EnrichedMarkdownText.d.ts.map +1 -1
- package/lib/typescript/src/web/parseMarkdown.d.ts +1 -1
- package/lib/typescript/src/web/parseMarkdown.d.ts.map +1 -1
- package/lib/typescript/src/web/renderers/InlineRenderers.d.ts.map +1 -1
- package/lib/typescript/src/web/renderers/ListRenderers.d.ts.map +1 -1
- package/lib/typescript/src/web/renderers/index.d.ts +2 -1
- package/lib/typescript/src/web/renderers/index.d.ts.map +1 -1
- package/lib/typescript/src/web/styles.d.ts +2 -1
- package/lib/typescript/src/web/styles.d.ts.map +1 -1
- package/lib/typescript/src/web/types.d.ts +6 -2
- package/lib/typescript/src/web/types.d.ts.map +1 -1
- package/lib/typescript/src/web/utils.d.ts.map +1 -1
- package/package.json +36 -9
- package/postinstall.mjs +131 -0
- package/ratex-version.json +21 -0
- package/src/EnrichedMarkdownNativeComponent.ts +65 -0
- package/src/EnrichedMarkdownTextInput.tsx +162 -8
- package/src/EnrichedMarkdownTextInputNativeComponent.ts +89 -5
- package/src/EnrichedMarkdownTextNativeComponent.ts +66 -0
- package/src/headingDefaults.ts +21 -0
- package/src/index.tsx +9 -0
- package/src/index.web.tsx +1 -0
- package/src/jest/index.tsx +215 -0
- package/src/native/EnrichedMarkdownText.tsx +40 -2
- package/src/normalizeMarkdownStyle.ts +102 -16
- package/src/normalizeMarkdownStyle.web.ts +63 -15
- package/src/normalizeMarkdownTextInputStyle.ts +110 -35
- package/src/normalizeMenuItem.ts +1 -1
- package/src/types/MarkdownStyle.ts +74 -0
- package/src/types/MarkdownStyleInternal.ts +39 -0
- package/src/types/MarkdownTextProps.ts +65 -0
- package/src/types/MarkdownTextProps.web.ts +19 -0
- package/src/types/events.ts +21 -0
- package/src/utils/textInputState.ts +35 -0
- package/src/web/EnrichedMarkdownText.tsx +16 -2
- package/src/web/parseMarkdown.ts +6 -2
- package/src/web/renderers/InlineRenderers.tsx +5 -0
- package/src/web/renderers/ListRenderers.tsx +14 -2
- package/src/web/renderers/index.tsx +6 -2
- package/src/web/styles.ts +89 -5
- package/src/web/types.ts +6 -1
- package/src/web/utils.ts +1 -0
- package/src/web/wasm/md4c.js +0 -0
- package/vendor-grammars.mjs +511 -0
- package/vendor-ratex.mjs +173 -0
- package/app.plugin.js +0 -2
- package/plugin/build/withAndroidMath.js +0 -19
- package/plugin/build/withIosMath.js +0 -28
- package/plugin/build/withReactNativeEnrichedMarkdown.js +0 -11
- package/plugin/src/withAndroidMath.ts +0 -24
- package/plugin/src/withIosMath.ts +0 -35
- package/plugin/src/withReactNativeEnrichedMarkdown.ts +0 -17
- package/plugin/tsconfig.build.json +0 -16
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
#import "ContextMenuUtils.h"
|
|
4
4
|
#import "ENRMAccessibilityLabels.h"
|
|
5
5
|
#import "ENRMAsyncRenderCoordinator.h"
|
|
6
|
+
#import "ENRMAtomicSize.h"
|
|
6
7
|
#import "ENRMContextMenuTextView+macOS.h"
|
|
7
8
|
#import "ENRMImageAttachment.h"
|
|
8
9
|
#import "ENRMMarkdownParser.h"
|
|
@@ -17,6 +18,7 @@
|
|
|
17
18
|
#import "FontScaleObserver.h"
|
|
18
19
|
#import "FontUtils.h"
|
|
19
20
|
#import "HeightUpdateUtils.h"
|
|
21
|
+
#import "ImageRequestHeaderUtils.h"
|
|
20
22
|
#import "LinkTapUtils.h"
|
|
21
23
|
#import "MarkdownASTNode.h"
|
|
22
24
|
#import "MarkdownAccessibilityElementBuilder.h"
|
|
@@ -45,8 +47,8 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
45
47
|
ENRMDirtyRender = 1 << 0,
|
|
46
48
|
};
|
|
47
49
|
|
|
48
|
-
@interface EnrichedMarkdownText () <RCTEnrichedMarkdownTextViewProtocol, UITextViewDelegate>
|
|
49
|
-
|
|
50
|
+
@interface EnrichedMarkdownText () <RCTEnrichedMarkdownTextViewProtocol, UITextViewDelegate, ENRMImageLayoutObserver>
|
|
51
|
+
+ (ENRMMd4cFlags *)flagsFromProps:(const EnrichedMarkdownTextMd4cFlagsStruct &)props;
|
|
50
52
|
- (void)setupTextView;
|
|
51
53
|
- (void)renderMarkdownContent:(NSString *)markdownString;
|
|
52
54
|
- (void)applyRenderedText:(NSMutableAttributedString *)attributedText;
|
|
@@ -80,6 +82,8 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
80
82
|
CGFloat _lastElementMarginBottom;
|
|
81
83
|
BOOL _allowTrailingMargin;
|
|
82
84
|
BOOL _enableLinkPreview;
|
|
85
|
+
BOOL _enableTaskListItemToggle;
|
|
86
|
+
BOOL _contextMenuHidden;
|
|
83
87
|
BOOL _streamingAnimation;
|
|
84
88
|
BOOL _forceHeightUpdateOnNextRender;
|
|
85
89
|
|
|
@@ -111,6 +115,8 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
111
115
|
NSWritingDirection _resolvedLayoutDirection;
|
|
112
116
|
|
|
113
117
|
ENRMDirtyFlags _dirtyFlags;
|
|
118
|
+
|
|
119
|
+
ENRMAtomicSize _lastCommittedSize;
|
|
114
120
|
}
|
|
115
121
|
|
|
116
122
|
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
|
@@ -118,6 +124,18 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
118
124
|
return concreteComponentDescriptorProvider<EnrichedMarkdownTextComponentDescriptor>();
|
|
119
125
|
}
|
|
120
126
|
|
|
127
|
+
+ (ENRMMd4cFlags *)flagsFromProps:(const EnrichedMarkdownTextMd4cFlagsStruct &)props
|
|
128
|
+
{
|
|
129
|
+
ENRMMd4cFlags *flags = [ENRMMd4cFlags defaultFlags];
|
|
130
|
+
flags.underline = props.underline;
|
|
131
|
+
flags.superscript = props.superscript;
|
|
132
|
+
flags.subscript = props.subscript;
|
|
133
|
+
flags.latexMath = props.latexMath;
|
|
134
|
+
flags.highlight = props.highlight;
|
|
135
|
+
flags.hardSoftBreaks = props.hardSoftBreaks;
|
|
136
|
+
return flags;
|
|
137
|
+
}
|
|
138
|
+
|
|
121
139
|
#pragma mark - Measuring and State
|
|
122
140
|
|
|
123
141
|
- (CGSize)measureSize:(CGFloat)maxWidth
|
|
@@ -130,6 +148,11 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
130
148
|
return size;
|
|
131
149
|
}
|
|
132
150
|
|
|
151
|
+
- (CGSize)lastCommittedLayoutSize
|
|
152
|
+
{
|
|
153
|
+
return _lastCommittedSize.load();
|
|
154
|
+
}
|
|
155
|
+
|
|
133
156
|
- (BOOL)hasRenderedMarkdown:(NSString *)markdown
|
|
134
157
|
{
|
|
135
158
|
return _renderedMarkdown != nil && [_renderedMarkdown isEqualToString:markdown];
|
|
@@ -158,6 +181,8 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
158
181
|
{
|
|
159
182
|
[super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
|
|
160
183
|
|
|
184
|
+
_lastCommittedSize.store(CGSizeMake(layoutMetrics.frame.size.width, layoutMetrics.frame.size.height));
|
|
185
|
+
|
|
161
186
|
NSWritingDirection resolved = _resolvedLayoutDirection;
|
|
162
187
|
if (layoutMetrics.layoutDirection == LayoutDirection::RightToLeft) {
|
|
163
188
|
resolved = NSWritingDirectionRightToLeft;
|
|
@@ -178,44 +203,21 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
178
203
|
ENRMRequestHeightUpdate<EnrichedMarkdownTextState>(_state, _heightUpdateCounter, self);
|
|
179
204
|
}
|
|
180
205
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
/// baselines cannot drift apart.
|
|
190
|
-
///
|
|
191
|
-
/// Requires `_fontScaleObserver` to already exist.
|
|
192
|
-
- (void)resetPropDerivedState
|
|
193
|
-
{
|
|
194
|
-
// Discarded rather than cleared field-by-field: the style diff can only clear a
|
|
195
|
-
// field when new and old differ, which never holds against a reset baseline.
|
|
196
|
-
_config = nil;
|
|
197
|
-
_spoilerManager = nil;
|
|
198
|
-
|
|
199
|
-
_md4cFlags = [ENRMMd4cFlags propsDefaultFlags];
|
|
200
|
-
_maxFontSizeMultiplier = 0;
|
|
201
|
-
_allowTrailingMargin = NO;
|
|
202
|
-
_fontScaleObserver.allowFontScaling = YES;
|
|
203
|
-
_streamingAnimation = NO;
|
|
204
|
-
_lineBreakStrategy = NSLineBreakStrategyNone;
|
|
205
|
-
_writingDirectionMode = ENRMWritingDirectionModeFirstStrong;
|
|
206
|
-
_contextMenuItemTexts = nil;
|
|
207
|
-
_contextMenuItemIcons = nil;
|
|
208
|
-
_accessibilityLabels = nil;
|
|
209
|
-
|
|
210
|
-
// Written only once a render completes, so stale until the next one lands.
|
|
211
|
-
_renderedStyleFingerprint = 0;
|
|
212
|
-
_pendingStyleFingerprint = 0;
|
|
213
|
-
_lastElementMarginBottom = 0;
|
|
206
|
+
// A block image resolved its box height after loading (maxHeight/aspectRatio
|
|
207
|
+
// sizing). The shadow node measured — and cached — this markdown with the
|
|
208
|
+
// pre-load fallback height, so drop those entries and re-measure.
|
|
209
|
+
- (void)imageAttachmentDidResolveLayout
|
|
210
|
+
{
|
|
211
|
+
if (_renderedMarkdown.length > 0) {
|
|
212
|
+
facebook::react::MeasurementCache::shared().removeMatchingMarkdown(std::string(_renderedMarkdown.UTF8String));
|
|
213
|
+
}
|
|
214
214
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
215
|
+
if (self.bounds.size.width > 0) {
|
|
216
|
+
CGSize measured = [self measureSize:self.bounds.size.width];
|
|
217
|
+
if (needsHeightUpdate(measured, self.bounds)) {
|
|
218
|
+
[self requestHeightUpdate];
|
|
219
|
+
}
|
|
220
|
+
}
|
|
219
221
|
}
|
|
220
222
|
|
|
221
223
|
- (instancetype)initWithFrame:(CGRect)frame
|
|
@@ -226,18 +228,25 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
226
228
|
|
|
227
229
|
self.backgroundColor = [RCTUIColor clearColor];
|
|
228
230
|
_parser = [[ENRMMarkdownParser alloc] init];
|
|
231
|
+
_md4cFlags = [EnrichedMarkdownText flagsFromProps:defaultProps->md4cFlags];
|
|
229
232
|
|
|
230
233
|
_renderCoordinator =
|
|
231
234
|
[[ENRMAsyncRenderCoordinator alloc] initWithQueueLabel:"com.swmansion.enriched.markdown.render"];
|
|
232
235
|
|
|
236
|
+
_maxFontSizeMultiplier = 0;
|
|
237
|
+
_allowTrailingMargin = NO;
|
|
233
238
|
_enableLinkPreview = YES;
|
|
239
|
+
_enableTaskListItemToggle = YES;
|
|
240
|
+
_forceHeightUpdateOnNextRender = NO;
|
|
241
|
+
_contextMenuHidden = NO;
|
|
234
242
|
_selectionMenuConfig = (ENRMSelectionMenuConfig){.copyAsMarkdown = YES, .copyImageURL = YES};
|
|
243
|
+
_lineBreakStrategy = NSLineBreakStrategyNone;
|
|
244
|
+
_writingDirectionMode = ENRMWritingDirectionModeFirstStrong;
|
|
235
245
|
_resolvedLayoutDirection =
|
|
236
246
|
[[RCTI18nUtil sharedInstance] isRTL] ? NSWritingDirectionRightToLeft : NSWritingDirectionLeftToRight;
|
|
247
|
+
_dirtyFlags = ENRMDirtyNone;
|
|
237
248
|
|
|
238
249
|
_fontScaleObserver = [[FontScaleObserver alloc] init];
|
|
239
|
-
[self resetPropDerivedState];
|
|
240
|
-
|
|
241
250
|
__weak EnrichedMarkdownText *weakSelf = self;
|
|
242
251
|
_fontScaleObserver.onChange = ^{
|
|
243
252
|
EnrichedMarkdownText *strongSelf = weakSelf;
|
|
@@ -280,6 +289,9 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
280
289
|
if (!strongSelf) {
|
|
281
290
|
return baseMenu;
|
|
282
291
|
}
|
|
292
|
+
if (strongSelf->_contextMenuHidden) {
|
|
293
|
+
return nil;
|
|
294
|
+
}
|
|
283
295
|
NSArray<NSMenuItem *> *customItems = ENRMBuildContextMenuItems(
|
|
284
296
|
strongSelf->_contextMenuItemTexts, strongSelf->_contextMenuItemIcons, textView,
|
|
285
297
|
^(NSString *itemText, NSString *selectedText, NSUInteger selectionStart, NSUInteger selectionEnd) {
|
|
@@ -495,6 +507,11 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
495
507
|
_dirtyFlags |= ENRMDirtyRender;
|
|
496
508
|
}
|
|
497
509
|
|
|
510
|
+
if (ENRMImageRequestHeadersChanged(oldViewProps.imageRequestHeaders, newViewProps.imageRequestHeaders)) {
|
|
511
|
+
[_config setImageRequestHeaders:ENRMImageRequestHeadersFromProps(newViewProps.imageRequestHeaders)];
|
|
512
|
+
_dirtyFlags |= ENRMDirtyRender;
|
|
513
|
+
}
|
|
514
|
+
|
|
498
515
|
NSLayoutManager *layoutManager = _textView.layoutManager;
|
|
499
516
|
if ([layoutManager isKindOfClass:[TextViewLayoutManager class]]) {
|
|
500
517
|
StyleConfig *currentConfig = [layoutManager valueForKey:@"config"];
|
|
@@ -539,33 +556,20 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
539
556
|
_dirtyFlags |= ENRMDirtyRender;
|
|
540
557
|
}
|
|
541
558
|
|
|
542
|
-
if (newViewProps.md4cFlags.underline != oldViewProps.md4cFlags.underline
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
_md4cFlags
|
|
549
|
-
_forceHeightUpdateOnNextRender = YES;
|
|
550
|
-
_dirtyFlags |= ENRMDirtyRender;
|
|
551
|
-
}
|
|
552
|
-
if (newViewProps.md4cFlags.subscript != oldViewProps.md4cFlags.subscript) {
|
|
553
|
-
_md4cFlags.subscript = newViewProps.md4cFlags.subscript;
|
|
554
|
-
_forceHeightUpdateOnNextRender = YES;
|
|
555
|
-
_dirtyFlags |= ENRMDirtyRender;
|
|
556
|
-
}
|
|
557
|
-
if (newViewProps.md4cFlags.latexMath != oldViewProps.md4cFlags.latexMath) {
|
|
558
|
-
_md4cFlags.latexMath = newViewProps.md4cFlags.latexMath;
|
|
559
|
-
_forceHeightUpdateOnNextRender = YES;
|
|
560
|
-
_dirtyFlags |= ENRMDirtyRender;
|
|
561
|
-
}
|
|
562
|
-
if (newViewProps.md4cFlags.highlight != oldViewProps.md4cFlags.highlight) {
|
|
563
|
-
_md4cFlags.highlight = newViewProps.md4cFlags.highlight;
|
|
559
|
+
if (newViewProps.md4cFlags.underline != oldViewProps.md4cFlags.underline ||
|
|
560
|
+
newViewProps.md4cFlags.superscript != oldViewProps.md4cFlags.superscript ||
|
|
561
|
+
newViewProps.md4cFlags.subscript != oldViewProps.md4cFlags.subscript ||
|
|
562
|
+
newViewProps.md4cFlags.latexMath != oldViewProps.md4cFlags.latexMath ||
|
|
563
|
+
newViewProps.md4cFlags.highlight != oldViewProps.md4cFlags.highlight ||
|
|
564
|
+
newViewProps.md4cFlags.hardSoftBreaks != oldViewProps.md4cFlags.hardSoftBreaks) {
|
|
565
|
+
_md4cFlags = [EnrichedMarkdownText flagsFromProps:newViewProps.md4cFlags];
|
|
564
566
|
_forceHeightUpdateOnNextRender = YES;
|
|
565
567
|
_dirtyFlags |= ENRMDirtyRender;
|
|
566
568
|
}
|
|
567
569
|
|
|
568
570
|
_enableLinkPreview = newViewProps.enableLinkPreview;
|
|
571
|
+
_enableTaskListItemToggle = newViewProps.enableTaskListItemToggle;
|
|
572
|
+
_contextMenuHidden = newViewProps.contextMenuHidden;
|
|
569
573
|
|
|
570
574
|
if (ENRMContextMenuItemsChanged(oldViewProps.contextMenuItems, newViewProps.contextMenuItems)) {
|
|
571
575
|
_contextMenuItemTexts = ENRMContextMenuTextsFromItems(newViewProps.contextMenuItems);
|
|
@@ -665,26 +669,46 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
665
669
|
|
|
666
670
|
- (void)prepareForRecycle
|
|
667
671
|
{
|
|
668
|
-
|
|
672
|
+
const auto resetProps = std::make_shared<const EnrichedMarkdownTextProps>();
|
|
673
|
+
_props = resetProps;
|
|
669
674
|
[_renderCoordinator invalidate];
|
|
670
675
|
|
|
671
676
|
[_fadeAnimator cancel];
|
|
672
677
|
_fadeAnimator = nil;
|
|
673
678
|
_previousTextLength = 0;
|
|
679
|
+
_streamingAnimation = NO;
|
|
680
|
+
_forceHeightUpdateOnNextRender = NO;
|
|
674
681
|
_cachedMarkdown = nil;
|
|
675
682
|
_renderedMarkdown = nil;
|
|
683
|
+
_config = nil;
|
|
684
|
+
_md4cFlags = [EnrichedMarkdownText flagsFromProps:resetProps->md4cFlags];
|
|
685
|
+
_maxFontSizeMultiplier = 0;
|
|
686
|
+
_lastElementMarginBottom = 0;
|
|
687
|
+
_allowTrailingMargin = NO;
|
|
688
|
+
_lineBreakStrategy = NSLineBreakStrategyNone;
|
|
689
|
+
_writingDirectionMode = ENRMWritingDirectionModeFirstStrong;
|
|
690
|
+
_renderedStyleFingerprint = 0;
|
|
691
|
+
_pendingStyleFingerprint = 0;
|
|
692
|
+
_contextMenuItemTexts = nil;
|
|
693
|
+
_contextMenuItemIcons = nil;
|
|
694
|
+
_fontScaleObserver.allowFontScaling = resetProps->allowFontScaling;
|
|
695
|
+
_accessibilityLabels = nil;
|
|
676
696
|
_accessibilityElements = nil;
|
|
677
697
|
_accessibilityInfo = nil;
|
|
678
698
|
_accessibilityNeedsRebuild = NO;
|
|
679
699
|
[_spoilerManager removeAllOverlays];
|
|
680
|
-
|
|
681
|
-
[self resetPropDerivedState];
|
|
682
|
-
|
|
700
|
+
_spoilerManager = nil;
|
|
683
701
|
if (_textView != nil) {
|
|
684
702
|
ENRMSetAttributedText(_textView, [[NSAttributedString alloc] initWithString:@""]);
|
|
685
703
|
_textView.hidden = YES;
|
|
686
704
|
}
|
|
687
705
|
|
|
706
|
+
// Ported from the fork's resetPropDerivedState: upstream's prepareForRecycle covers every
|
|
707
|
+
// other prop-derived ivar but leaves these two, so a recycled view keeps the previous
|
|
708
|
+
// consumer's height-update counter and a dangling shadow-node state handle.
|
|
709
|
+
_heightUpdateCounter = 0;
|
|
710
|
+
_state = nullptr;
|
|
711
|
+
|
|
688
712
|
[super prepareForRecycle];
|
|
689
713
|
}
|
|
690
714
|
|
|
@@ -745,7 +769,8 @@ Class<RCTComponentViewProtocol> EnrichedMarkdownTextCls(void)
|
|
|
745
769
|
{
|
|
746
770
|
ENRMPlatformTextView *textView = (ENRMPlatformTextView *)recognizer.view;
|
|
747
771
|
|
|
748
|
-
if (
|
|
772
|
+
if (_enableTaskListItemToggle &&
|
|
773
|
+
handleTaskListTapWithSharedLogic(
|
|
749
774
|
textView, recognizer, &self->_cachedMarkdown, self->_config,
|
|
750
775
|
^(NSInteger index, BOOL checked, NSString *itemText) {
|
|
751
776
|
[self emitTaskListItemPress:index checked:checked text:itemText];
|
|
@@ -790,6 +815,10 @@ Class<RCTComponentViewProtocol> EnrichedMarkdownTextCls(void)
|
|
|
790
815
|
editMenuForTextInRange:(NSRange)range
|
|
791
816
|
suggestedActions:(NSArray<UIMenuElement *> *)suggestedActions API_AVAILABLE(ios(16.0))
|
|
792
817
|
{
|
|
818
|
+
if (_contextMenuHidden) {
|
|
819
|
+
return nil;
|
|
820
|
+
}
|
|
821
|
+
|
|
793
822
|
__weak EnrichedMarkdownText *weakSelf = self;
|
|
794
823
|
ENRMContextMenuPressHandler handler =
|
|
795
824
|
^(NSString *itemText, NSString *selectedText, NSUInteger selectionStart, NSUInteger selectionEnd) {
|
|
@@ -5,6 +5,15 @@
|
|
|
5
5
|
|
|
6
6
|
NS_ASSUME_NONNULL_BEGIN
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Adopted by component views that host markdown text. Notified when a block
|
|
10
|
+
* image resolves its box height after loading (maxHeight/aspectRatio sizing),
|
|
11
|
+
* so the view can drop stale cached measurements and request a height update.
|
|
12
|
+
*/
|
|
13
|
+
@protocol ENRMImageLayoutObserver
|
|
14
|
+
- (void)imageAttachmentDidResolveLayout;
|
|
15
|
+
@end
|
|
16
|
+
|
|
8
17
|
/**
|
|
9
18
|
* Custom NSTextAttachment for rendering markdown images.
|
|
10
19
|
* Images are loaded asynchronously and scaled dynamically based on text container width.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
#import "StyleConfig.h"
|
|
6
6
|
#import <objc/runtime.h>
|
|
7
7
|
|
|
8
|
-
#define CACHE_KEY_PROCESSED(url, w, h, r) [NSString stringWithFormat:@"%@_w%.1f_h%.1f_r%.
|
|
8
|
+
#define CACHE_KEY_PROCESSED(url, w, h, r, m) [NSString stringWithFormat:@"%@_w%.1f_h%.1f_r%.1f_m%@", url, w, h, r, m]
|
|
9
9
|
|
|
10
10
|
static inline NSUInteger ENRMImageByteCost(RCTUIImage *image)
|
|
11
11
|
{
|
|
@@ -22,13 +22,19 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
|
|
|
22
22
|
@interface ENRMImageAttachment ()
|
|
23
23
|
|
|
24
24
|
@property (nonatomic, copy) NSString *imageURL;
|
|
25
|
+
@property (nonatomic, copy, nullable) NSDictionary<NSString *, NSString *> *requestHeaders;
|
|
26
|
+
@property (nonatomic, copy) NSString *cacheKey;
|
|
25
27
|
@property (nonatomic, assign) BOOL isInline;
|
|
26
28
|
@property (nonatomic, assign) CGFloat cachedHeight;
|
|
29
|
+
@property (nonatomic, assign) CGFloat cachedMaxHeight;
|
|
30
|
+
@property (nonatomic, assign) CGFloat cachedAspectRatio;
|
|
31
|
+
@property (nonatomic, copy) NSString *cachedResizeMode;
|
|
27
32
|
@property (nonatomic, assign) CGFloat cachedBorderRadius;
|
|
28
33
|
@property (nonatomic, weak) NSTextContainer *textContainer;
|
|
29
34
|
@property (nonatomic, weak) ENRMPlatformTextView *textView;
|
|
30
35
|
@property (nonatomic, strong) RCTUIImage *originalImage;
|
|
31
36
|
@property (nonatomic, strong) RCTUIImage *loadedImage;
|
|
37
|
+
@property (nonatomic, strong) RCTUIImage *placeholderImage;
|
|
32
38
|
@property (nonatomic, copy) NSString *lastProcessedKey;
|
|
33
39
|
|
|
34
40
|
@end
|
|
@@ -66,7 +72,8 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
|
|
|
66
72
|
|
|
67
73
|
+ (instancetype)attachmentForURL:(NSString *)imageURL config:(StyleConfig *)config isInline:(BOOL)isInline
|
|
68
74
|
{
|
|
69
|
-
NSString *key =
|
|
75
|
+
NSString *key =
|
|
76
|
+
[NSString stringWithFormat:@"%@_%d", ENRMImageCacheKey(imageURL, [config imageRequestHeaders]), isInline];
|
|
70
77
|
ENRMImageAttachment *existing = [[self attachmentRegistry] objectForKey:key];
|
|
71
78
|
if (existing && existing.loadedImage) {
|
|
72
79
|
return existing;
|
|
@@ -86,9 +93,14 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
|
|
|
86
93
|
self = [super init];
|
|
87
94
|
if (self) {
|
|
88
95
|
_imageURL = imageURL;
|
|
96
|
+
_requestHeaders = [[config imageRequestHeaders] copy];
|
|
97
|
+
_cacheKey = ENRMImageCacheKey(imageURL, _requestHeaders);
|
|
89
98
|
_isInline = isInline;
|
|
90
99
|
|
|
91
100
|
_cachedHeight = isInline ? [config inlineImageSize] : [config imageHeight];
|
|
101
|
+
_cachedMaxHeight = [config imageMaxHeight];
|
|
102
|
+
_cachedAspectRatio = [config imageAspectRatio];
|
|
103
|
+
_cachedResizeMode = [config imageResizeMode];
|
|
92
104
|
_cachedBorderRadius = [config imageBorderRadius];
|
|
93
105
|
|
|
94
106
|
[self setupPlaceholder];
|
|
@@ -97,6 +109,33 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
|
|
|
97
109
|
return self;
|
|
98
110
|
}
|
|
99
111
|
|
|
112
|
+
- (CGFloat)resolvedBoxHeightForWidth:(CGFloat)width
|
|
113
|
+
{
|
|
114
|
+
if (self.cachedAspectRatio > 0 && width > 0) {
|
|
115
|
+
return width / self.cachedAspectRatio;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (self.cachedMaxHeight > 0) {
|
|
119
|
+
RCTUIImage *source = self.originalImage;
|
|
120
|
+
if (source && width > 0 && source.size.width > 0 && source.size.height > 0) {
|
|
121
|
+
CGFloat fitted = width * source.size.height / source.size.width;
|
|
122
|
+
return MIN(self.cachedMaxHeight, fitted);
|
|
123
|
+
}
|
|
124
|
+
// Intrinsic size not known yet — fall back to the full max height; the box
|
|
125
|
+
// shrinks once the image loads and layout is invalidated.
|
|
126
|
+
return self.cachedMaxHeight;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return self.cachedHeight;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// True when resizeMode is unset ('') - legacy always implies a fixed height box.
|
|
133
|
+
|
|
134
|
+
- (BOOL)isLegacyBlockSizing
|
|
135
|
+
{
|
|
136
|
+
return !self.isInline && self.cachedResizeMode.length == 0;
|
|
137
|
+
}
|
|
138
|
+
|
|
100
139
|
- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer
|
|
101
140
|
proposedLineFragment:(CGRect)lineFragment
|
|
102
141
|
glyphPosition:(CGPoint)position
|
|
@@ -105,26 +144,27 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
|
|
|
105
144
|
CGFloat height = self.cachedHeight;
|
|
106
145
|
CGFloat width = self.isInline ? height : (lineFragment.size.width > 0 ? lineFragment.size.width : height);
|
|
107
146
|
|
|
108
|
-
if (self.isInline) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
147
|
+
if (!self.isInline) {
|
|
148
|
+
height = [self resolvedBoxHeightForWidth:width];
|
|
149
|
+
return CGRectMake(0, 0, width, height);
|
|
150
|
+
}
|
|
112
151
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
152
|
+
UIFont *appliedFont = nil;
|
|
153
|
+
NSLayoutManager *layoutManager = textContainer.layoutManager;
|
|
154
|
+
NSTextStorage *textStorage = layoutManager.textStorage;
|
|
116
155
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
} else {
|
|
121
|
-
verticalOffset = (lineFragment.size.height - height) / 2.0;
|
|
122
|
-
}
|
|
156
|
+
if (textStorage && characterIndex < textStorage.length) {
|
|
157
|
+
appliedFont = [textStorage attribute:NSFontAttributeName atIndex:characterIndex effectiveRange:NULL];
|
|
158
|
+
}
|
|
123
159
|
|
|
124
|
-
|
|
160
|
+
CGFloat verticalOffset;
|
|
161
|
+
if (appliedFont) {
|
|
162
|
+
verticalOffset = (appliedFont.capHeight - height) / 2.0;
|
|
163
|
+
} else {
|
|
164
|
+
verticalOffset = (lineFragment.size.height - height) / 2.0;
|
|
125
165
|
}
|
|
126
166
|
|
|
127
|
-
return CGRectMake(0,
|
|
167
|
+
return CGRectMake(0, verticalOffset, width, height);
|
|
128
168
|
}
|
|
129
169
|
|
|
130
170
|
- (RCTUIImage *)imageForBounds:(CGRect)imageBounds
|
|
@@ -138,7 +178,7 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
|
|
|
138
178
|
[self processAndApplyImage:self.originalImage withTargetWidth:imageBounds.size.width];
|
|
139
179
|
}
|
|
140
180
|
|
|
141
|
-
return self.loadedImage ?: self.
|
|
181
|
+
return self.loadedImage ?: self.placeholderImage;
|
|
142
182
|
}
|
|
143
183
|
|
|
144
184
|
- (void)handleLoadedImage:(RCTUIImage *)image
|
|
@@ -146,7 +186,15 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
|
|
|
146
186
|
if (!image)
|
|
147
187
|
return;
|
|
148
188
|
|
|
189
|
+
// The downloader completes synchronously on cache hits, which can happen on the render queue
|
|
190
|
+
if (!NSThread.isMainThread) {
|
|
191
|
+
dispatch_async(dispatch_get_main_queue(), ^{ [self handleLoadedImage:image]; });
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
149
195
|
self.originalImage = image;
|
|
196
|
+
// UIKit reads the plain image property for save/drag/copy — it must hold the original
|
|
197
|
+
self.image = image;
|
|
150
198
|
CGFloat targetWidth = self.isInline ? self.cachedHeight : self.bounds.size.width;
|
|
151
199
|
|
|
152
200
|
// Defer processing if we don't have valid bounds yet (common for non-inline block images)
|
|
@@ -162,7 +210,10 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
|
|
|
162
210
|
if (targetWidth <= 0)
|
|
163
211
|
return;
|
|
164
212
|
|
|
165
|
-
|
|
213
|
+
CGFloat boxHeight = self.isInline ? self.cachedHeight : [self resolvedBoxHeightForWidth:targetWidth];
|
|
214
|
+
|
|
215
|
+
NSString *processedKey =
|
|
216
|
+
CACHE_KEY_PROCESSED(self.cacheKey, targetWidth, boxHeight, self.cachedBorderRadius, self.cachedResizeMode);
|
|
166
217
|
|
|
167
218
|
if ([processedKey isEqualToString:self.lastProcessedKey])
|
|
168
219
|
return;
|
|
@@ -172,8 +223,6 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
|
|
|
172
223
|
|
|
173
224
|
if (cachedProcessed) {
|
|
174
225
|
self.loadedImage = cachedProcessed;
|
|
175
|
-
if (self.isInline)
|
|
176
|
-
self.image = cachedProcessed;
|
|
177
226
|
[self refreshDisplay];
|
|
178
227
|
return;
|
|
179
228
|
}
|
|
@@ -186,7 +235,7 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
|
|
|
186
235
|
|
|
187
236
|
RCTUIImage *processedImage = [strongSelf createScaledImage:image
|
|
188
237
|
toWidth:targetWidth
|
|
189
|
-
height:
|
|
238
|
+
height:boxHeight
|
|
190
239
|
borderRadius:strongSelf.cachedBorderRadius];
|
|
191
240
|
|
|
192
241
|
if (processedImage) {
|
|
@@ -198,10 +247,7 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
|
|
|
198
247
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
199
248
|
strongSelf.loadedImage = processedImage;
|
|
200
249
|
if (strongSelf.isInline) {
|
|
201
|
-
strongSelf.image = processedImage;
|
|
202
250
|
strongSelf.bounds = CGRectMake(0, 0, strongSelf.cachedHeight, strongSelf.cachedHeight);
|
|
203
|
-
} else {
|
|
204
|
-
strongSelf.image = image; // Keep original for layout references
|
|
205
251
|
}
|
|
206
252
|
[strongSelf refreshDisplay];
|
|
207
253
|
});
|
|
@@ -218,32 +264,64 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
|
|
|
218
264
|
if (sourceWidth <= 0 || sourceHeight <= 0)
|
|
219
265
|
return nil;
|
|
220
266
|
|
|
221
|
-
|
|
267
|
+
CGSize source = CGSizeMake(sourceWidth, sourceHeight);
|
|
268
|
+
CGSize box = CGSizeMake(targetWidth, targetHeight);
|
|
269
|
+
BOOL legacy = [self isLegacyBlockSizing];
|
|
222
270
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
drawingWidth
|
|
226
|
-
|
|
271
|
+
CGRect drawingRect;
|
|
272
|
+
if (self.isInline || legacy) {
|
|
273
|
+
CGFloat drawingWidth, drawingHeight;
|
|
274
|
+
if (!self.isInline) {
|
|
275
|
+
CGFloat aspectRatioScale = targetWidth / sourceWidth;
|
|
276
|
+
drawingWidth = targetWidth;
|
|
277
|
+
drawingHeight = sourceHeight * aspectRatioScale;
|
|
278
|
+
} else {
|
|
279
|
+
drawingWidth = targetWidth;
|
|
280
|
+
drawingHeight = targetHeight;
|
|
281
|
+
}
|
|
282
|
+
drawingRect = CGRectMake((targetWidth - drawingWidth) / 2.0, (targetHeight - drawingHeight) / 2.0, drawingWidth,
|
|
283
|
+
drawingHeight);
|
|
227
284
|
} else {
|
|
228
|
-
|
|
229
|
-
drawingHeight = targetHeight;
|
|
285
|
+
drawingRect = [self drawingRectForResizeMode:self.cachedResizeMode source:source box:box];
|
|
230
286
|
}
|
|
231
287
|
|
|
232
|
-
|
|
233
|
-
CGRectMake((targetWidth - drawingWidth) / 2.0, (targetHeight - drawingHeight) / 2.0, drawingWidth, drawingHeight);
|
|
234
|
-
|
|
235
|
-
RCTUIGraphicsImageRenderer *renderer = ImageRendererForSize(CGSizeMake(targetWidth, targetHeight));
|
|
288
|
+
RCTUIGraphicsImageRenderer *renderer = ImageRendererForSize(box);
|
|
236
289
|
|
|
237
290
|
return [renderer imageWithActions:^(RCTUIGraphicsImageRendererContext *context) {
|
|
238
291
|
if (radius > 0) {
|
|
239
|
-
CGRect
|
|
240
|
-
UIBezierPath *path = UIBezierPathWithRoundedRect(
|
|
292
|
+
CGRect clipRect = CGRectIntersection(CGRectMake(0, 0, targetWidth, targetHeight), drawingRect);
|
|
293
|
+
UIBezierPath *path = UIBezierPathWithRoundedRect(clipRect, radius);
|
|
241
294
|
[path addClip];
|
|
242
295
|
}
|
|
243
296
|
[image drawInRect:drawingRect];
|
|
244
297
|
}];
|
|
245
298
|
}
|
|
246
299
|
|
|
300
|
+
- (CGRect)drawingRectForResizeMode:(NSString *)mode source:(CGSize)source box:(CGSize)box
|
|
301
|
+
{
|
|
302
|
+
if ([mode isEqualToString:@"stretch"]) {
|
|
303
|
+
return CGRectMake(0, 0, box.width, box.height);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
CGFloat widthScale = box.width / source.width;
|
|
307
|
+
CGFloat heightScale = box.height / source.height;
|
|
308
|
+
|
|
309
|
+
CGFloat scale;
|
|
310
|
+
if ([mode isEqualToString:@"contain"]) {
|
|
311
|
+
scale = MIN(widthScale, heightScale);
|
|
312
|
+
} else if ([mode isEqualToString:@"center"]) {
|
|
313
|
+
scale = MIN(1.0, MIN(widthScale, heightScale));
|
|
314
|
+
} else if ([mode isEqualToString:@"none"]) {
|
|
315
|
+
scale = 1.0;
|
|
316
|
+
} else { // cover (default)
|
|
317
|
+
scale = MAX(widthScale, heightScale);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
CGFloat drawingWidth = source.width * scale;
|
|
321
|
+
CGFloat drawingHeight = source.height * scale;
|
|
322
|
+
return CGRectMake((box.width - drawingWidth) / 2.0, (box.height - drawingHeight) / 2.0, drawingWidth, drawingHeight);
|
|
323
|
+
}
|
|
324
|
+
|
|
247
325
|
- (void)startDownloadingImage
|
|
248
326
|
{
|
|
249
327
|
if (self.imageURL.length == 0)
|
|
@@ -251,6 +329,7 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
|
|
|
251
329
|
|
|
252
330
|
__weak typeof(self) weakSelf = self;
|
|
253
331
|
[[ENRMImageDownloader shared] downloadURL:self.imageURL
|
|
332
|
+
headers:self.requestHeaders
|
|
254
333
|
completion:^(RCTUIImage *image) { [weakSelf handleLoadedImage:image]; }];
|
|
255
334
|
}
|
|
256
335
|
|
|
@@ -265,10 +344,34 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
|
|
|
265
344
|
[textView.layoutManager invalidateDisplayForCharacterRange:range];
|
|
266
345
|
if (!self.isInline) {
|
|
267
346
|
[textView.layoutManager invalidateLayoutForCharacterRange:range actualCharacterRange:NULL];
|
|
347
|
+
[self notifyImageLayoutObserver:textView];
|
|
268
348
|
}
|
|
269
349
|
}
|
|
270
350
|
}
|
|
271
351
|
|
|
352
|
+
// With maxHeight/aspectRatio sizing the box height can settle after the image
|
|
353
|
+
// loads, while the component was measured (and its size cached) with the
|
|
354
|
+
// pre-load fallback. Notify the hosting component so it can re-measure.
|
|
355
|
+
// Dispatched async: refreshDisplay can run mid-layout (imageForBounds) and
|
|
356
|
+
// re-measuring would re-enter the layout manager.
|
|
357
|
+
- (void)notifyImageLayoutObserver:(UITextView *)textView
|
|
358
|
+
{
|
|
359
|
+
// Only maxHeight/aspectRatio boxes can change height after load; a fixed
|
|
360
|
+
// height box (legacy or explicit resizeMode) never needs a re-measure.
|
|
361
|
+
if (self.cachedMaxHeight <= 0 && self.cachedAspectRatio <= 0)
|
|
362
|
+
return;
|
|
363
|
+
|
|
364
|
+
RCTUIView *candidate = textView;
|
|
365
|
+
while (candidate && ![candidate conformsToProtocol:@protocol(ENRMImageLayoutObserver)]) {
|
|
366
|
+
candidate = candidate.superview;
|
|
367
|
+
}
|
|
368
|
+
if (!candidate)
|
|
369
|
+
return;
|
|
370
|
+
|
|
371
|
+
id<ENRMImageLayoutObserver> observer = (id<ENRMImageLayoutObserver>)candidate;
|
|
372
|
+
dispatch_async(dispatch_get_main_queue(), ^{ [observer imageAttachmentDidResolveLayout]; });
|
|
373
|
+
}
|
|
374
|
+
|
|
272
375
|
- (ENRMPlatformTextView *)fetchAssociatedTextView
|
|
273
376
|
{
|
|
274
377
|
if (self.textView)
|
|
@@ -284,7 +387,7 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
|
|
|
284
387
|
CGFloat size = self.cachedHeight;
|
|
285
388
|
self.bounds = CGRectMake(0, 0, size, size);
|
|
286
389
|
RCTUIGraphicsImageRenderer *renderer = [[RCTUIGraphicsImageRenderer alloc] initWithSize:CGSizeMake(1, 1)];
|
|
287
|
-
self.
|
|
390
|
+
self.placeholderImage = [renderer imageWithActions:^(RCTUIGraphicsImageRendererContext *ctx){}];
|
|
288
391
|
}
|
|
289
392
|
|
|
290
393
|
- (NSRange)findAttachmentRangeInText:(NSAttributedString *)attributedString
|
|
@@ -302,4 +405,4 @@ static NSMapTable<NSString *, ENRMImageAttachment *> *_attachmentRegistry;
|
|
|
302
405
|
return foundRange;
|
|
303
406
|
}
|
|
304
407
|
|
|
305
|
-
@end
|
|
408
|
+
@end
|
|
@@ -9,6 +9,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
9
9
|
@property (nonatomic, assign) CGFloat fontSize;
|
|
10
10
|
@property (nonatomic, strong, nullable) RCTUIColor *mathTextColor;
|
|
11
11
|
|
|
12
|
+
@property (nonatomic, readonly) CGFloat boxHeight;
|
|
13
|
+
|
|
12
14
|
/// Typeset the glyphs at bold weight (synthetic — see ENRMRaTeXBridge).
|
|
13
15
|
@property (nonatomic, assign) BOOL bold;
|
|
14
16
|
|