react-native-enriched-markdown-scaffold 0.7.4-scaffold.9 → 1.0.2-scaffold.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -8
- package/ReactNativeEnrichedMarkdown.podspec +82 -73
- package/android/build.gradle +186 -1
- package/android/consumer-rules.pro +1 -1
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +9 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +3 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerDelegate.java +24 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerInterface.java +8 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +9 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +3 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +35 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +886 -23
- package/android/src/main/baseline-prof.txt +1 -1
- package/android/src/main/cpp/jni-adapter.cpp +74 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +189 -13
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +50 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +48 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextLayoutManager.kt +10 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +42 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +82 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/events/CopyPressEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputManager.kt +54 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +901 -462
- package/android/src/main/java/com/swmansion/enriched/markdown/input/MarkdownClipboard.kt +42 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/BlockEditCoordinator.kt +196 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/ClipboardCoordinator.kt +73 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditContext.kt +19 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditPipeline.kt +248 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditSession.kt +52 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/InputConnectionWrapper.kt +101 -7
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/LinkCoordinator.kt +69 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MarkdownTextWatcher.kt +3 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MentionCoordinator.kt +118 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeStateEvent.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnContextMenuItemPressEvent.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnInputKeyPressEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnPasteEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockStore.kt +254 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/FormattingStore.kt +80 -87
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputFormatter.kt +109 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +116 -22
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/MarkdownSerializer.kt +167 -38
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/RangeEditAdjustment.kt +149 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputEventEmitter.kt +66 -5
- package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +4 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockRange.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockType.kt +48 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/FormattingRange.kt +9 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/InputFormatterStyle.kt +39 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathAtom.kt +20 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MutableRangeBounds.kt +11 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputBulletSpan.kt +82 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputHeadingSpan.kt +58 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputListItemSpacingSpan.kt +37 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputOrderedListMarkerSpan.kt +63 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/BlockHandler.kt +54 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/HeadingBlockHandler.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/OrderedListBlockHandler.kt +38 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/UnorderedListBlockHandler.kt +37 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +8 -26
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +9 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +100 -12
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +16 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +2 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +74 -18
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +43 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +9 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SoftBreakRenderer.kt +16 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +30 -27
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +174 -24
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +27 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +13 -16
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +182 -46
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListItemSpacingSpan.kt +33 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListMarkerAnchorSpan.kt +38 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +2 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +3 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +3 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +7 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +4 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +13 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockHighlighter.kt +90 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockNode.kt +57 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/FeatureFlags.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownSegment.kt +9 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +37 -7
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/ReadableMapExtensions.kt +3 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/RenderedSegment.kt +10 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentSignature.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/StreamingMarkdownFilter.kt +83 -5
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +74 -44
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/PasteTextUtils.kt +20 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +26 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +22 -9
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/LocalImageLoader.kt +161 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/TextPaintExtensions.kt +23 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/CheckboxTouchHelper.kt +7 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +41 -21
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt +15 -8
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLongPressMovementMethod.kt +58 -27
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +49 -15
- package/android/src/main/java/com/swmansion/enriched/markdown/views/BlockMenuOptions.kt +45 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +396 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/ContextMenuPopup.kt +9 -6
- package/android/src/main/java/com/swmansion/enriched/markdown/views/CopyGlyph.kt +101 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +36 -9
- package/android/src/main/jni/CMakeLists.txt +53 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.cpp +10 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +11 -2
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +10 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +12 -2
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.cpp +9 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.h +24 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +16 -0
- package/android/src/math/java/com/swmansion/enriched/markdown/input/math/MathChipControllerImpl.kt +21 -4
- package/android/src/math/java/com/swmansion/enriched/markdown/renderer/MathInlineRenderer.kt +7 -2
- package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +1 -1
- package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +6 -4
- package/cpp/highlight/CodeBlockHighlighter.cpp +284 -0
- package/cpp/highlight/CodeBlockHighlighter.hpp +66 -0
- package/cpp/highlight/CodeBlockLanguages.cpp +138 -0
- package/cpp/highlight/CodeBlockLanguages.hpp +25 -0
- package/cpp/highlight/HighlightGrammars.hpp +28 -0
- package/cpp/highlight/code_highlight_podspec.rb +211 -0
- package/cpp/highlight/gen-registry.mjs +155 -0
- package/cpp/highlight/grammar-versions.json +159 -0
- package/cpp/highlight/vendor/generated/generated_queries.h +1665 -0
- package/cpp/highlight/vendor/generated/generated_registry.cpp +59 -0
- package/cpp/parser/MD4CParser.cpp +173 -61
- package/cpp/parser/MD4CParser.hpp +1 -0
- package/cpp/parser/MarkdownASTNode.hpp +2 -1
- package/cpp/wasm/ASTSerializer.cpp +2 -0
- package/cpp/wasm/build.sh +1 -0
- package/cpp/wasm/md4c_wasm.cpp +3 -1
- package/docs/ACCESSIBILITY.md +14 -2
- package/docs/API_REFERENCE.md +234 -12
- package/docs/BREAKING_CHANGES.md +129 -0
- package/docs/CODE_HIGHLIGHT.md +133 -0
- package/docs/COPY_OPTIONS.md +47 -3
- package/docs/ELEMENTS_STRUCTURE.md +52 -4
- package/docs/IMAGE_CACHING.md +30 -0
- package/docs/INPUT.md +108 -11
- package/docs/LATEX_MATH.md +87 -45
- package/docs/MACOS.md +1 -1
- package/docs/MARKDOWN_STREAMING.md +27 -1
- package/docs/NATIVE_ASSETS.md +127 -0
- package/docs/RTL.md +1 -1
- package/docs/STYLES.md +46 -6
- package/docs/TESTING.md +112 -0
- package/docs/TEXT.md +16 -6
- package/docs/WEB.md +3 -1
- package/ios/EnrichedMarkdown.h +7 -0
- package/ios/EnrichedMarkdown.mm +284 -75
- package/ios/EnrichedMarkdownText.h +7 -0
- package/ios/EnrichedMarkdownText.mm +101 -73
- package/ios/attachments/ENRMImageAttachment.h +9 -0
- package/ios/attachments/ENRMImageAttachment.m +143 -40
- package/ios/attachments/ENRMMathInlineAttachment.h +2 -0
- package/ios/attachments/ENRMMathInlineAttachment.m +48 -81
- package/ios/attachments/ENRMMathInlineAttachmentShared.h +2 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +75 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +63 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +35 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +886 -23
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +131 -0
- package/ios/input/ENRMAutoLinkDetector.h +2 -1
- package/ios/input/ENRMAutoLinkDetector.mm +79 -41
- package/ios/input/ENRMBlockEditCoordinator.h +71 -0
- package/ios/input/ENRMBlockEditCoordinator.mm +195 -0
- package/ios/input/ENRMBlockRange.h +28 -0
- package/ios/input/ENRMBlockRange.mm +30 -0
- package/ios/input/ENRMBlockStore.h +56 -0
- package/ios/input/ENRMBlockStore.mm +275 -0
- package/ios/input/ENRMClipboardCoordinator.h +45 -0
- package/ios/input/ENRMClipboardCoordinator.mm +120 -0
- package/ios/input/ENRMDetectorPipeline.h +2 -1
- package/ios/input/ENRMEditPipeline.h +76 -0
- package/ios/input/ENRMEditPipeline.mm +228 -0
- package/ios/input/ENRMEditSession.h +36 -0
- package/ios/input/ENRMEditSession.mm +63 -0
- package/ios/input/ENRMFormattingStore.h +17 -0
- package/ios/input/ENRMFormattingStore.mm +95 -105
- package/ios/input/ENRMInputBlockType.h +91 -0
- package/ios/input/ENRMInputBlockType.mm +5 -0
- package/ios/input/ENRMInputDecorationDrawer.h +18 -0
- package/ios/input/ENRMInputEventEmitter.h +56 -0
- package/ios/input/ENRMInputEventEmitter.mm +308 -0
- package/ios/input/ENRMInputFormatter.h +29 -69
- package/ios/input/ENRMInputFormatter.mm +216 -124
- package/ios/input/ENRMInputFormatterStyle.h +99 -0
- package/ios/input/ENRMInputFormatterStyle.mm +188 -0
- package/ios/input/ENRMInputLayoutManager.h +9 -0
- package/ios/input/ENRMInputLayoutManager.mm +30 -0
- package/ios/input/ENRMInputListMarkerDrawer.h +32 -0
- package/ios/input/ENRMInputListMarkerDrawer.mm +426 -0
- package/ios/input/ENRMInputParser.h +5 -6
- package/ios/input/ENRMInputParser.mm +461 -178
- package/ios/input/ENRMInputRemend.mm +2 -2
- package/ios/input/ENRMInputStyleStateBuilder.h +40 -0
- package/ios/input/ENRMInputStyleStateBuilder.mm +60 -0
- package/ios/input/ENRMInputTextView.mm +103 -8
- package/ios/input/ENRMInputTypingAttributesController.h +42 -0
- package/ios/input/ENRMInputTypingAttributesController.mm +203 -0
- package/ios/input/ENRMLinkCoordinator.h +41 -0
- package/ios/input/ENRMLinkCoordinator.mm +89 -0
- package/ios/input/ENRMMarkdownSerializer.h +29 -5
- package/ios/input/ENRMMarkdownSerializer.mm +170 -48
- package/ios/input/ENRMMathAtom.h +26 -0
- package/ios/input/ENRMMathAtom.mm +12 -0
- package/ios/input/ENRMMentionCoordinator.h +45 -0
- package/ios/input/ENRMMentionCoordinator.mm +167 -0
- package/ios/input/ENRMRangeEditAdjustment.h +38 -0
- package/ios/input/ENRMRangeEditAdjustment.mm +91 -0
- package/ios/input/ENRMRangeStoreUtils.h +39 -0
- package/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm +6 -6
- package/ios/input/EnrichedMarkdownTextInput+Internal.h +11 -3
- package/ios/input/EnrichedMarkdownTextInput.h +7 -1
- package/ios/input/EnrichedMarkdownTextInput.mm +1089 -1023
- package/ios/input/InputStylePropsUtils.h +109 -68
- package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.mm +2 -1
- package/ios/input/styles/ENRMBlockHandler.h +46 -0
- package/ios/input/styles/ENRMHeadingBlockHandler.h +15 -0
- package/ios/input/styles/ENRMHeadingBlockHandler.mm +38 -0
- package/ios/input/styles/ENRMOrderedListBlockHandler.h +14 -0
- package/ios/input/styles/ENRMOrderedListBlockHandler.mm +48 -0
- package/ios/input/styles/ENRMUnorderedListBlockHandler.h +15 -0
- package/ios/input/styles/ENRMUnorderedListBlockHandler.mm +51 -0
- package/ios/internals/ENRMViewFreeMeasurement.h +331 -0
- package/ios/internals/EnrichedMarkdownShadowNode.h +1 -3
- package/ios/internals/EnrichedMarkdownShadowNode.mm +16 -20
- package/ios/internals/EnrichedMarkdownTextShadowNode.h +1 -3
- package/ios/internals/EnrichedMarkdownTextShadowNode.mm +15 -20
- package/ios/internals/MeasurementCache.h +33 -7
- package/ios/internals/ShadowMeasurementUtils.h +63 -58
- package/ios/math/ENRMMathChipController.h +74 -0
- package/ios/math/ENRMMathChipController.mm +476 -0
- package/ios/math/ENRMRaTeXBridge.swift +4 -1
- package/ios/parser/ENRMMarkdownParser.h +1 -8
- package/ios/parser/ENRMMarkdownParser.mm +2 -11
- package/ios/parser/MarkdownASTNode.h +2 -1
- package/ios/parser/MarkdownParserBridge.mm +4 -0
- package/ios/renderer/AttributedRenderer.m +20 -2
- package/ios/renderer/BaseRenderer.h +17 -2
- package/ios/renderer/BaseRenderer.m +30 -0
- package/ios/renderer/BlockquoteRenderer.h +1 -1
- package/ios/renderer/BlockquoteRenderer.m +144 -35
- package/ios/renderer/CodeBlockRenderer.h +1 -1
- package/ios/renderer/CodeBlockRenderer.m +27 -23
- package/ios/renderer/CodeRenderer.h +1 -1
- package/ios/renderer/CodeRenderer.m +3 -1
- package/ios/renderer/ENRMImageRenderer.h +1 -1
- package/ios/renderer/ENRMImageRenderer.m +5 -1
- package/ios/renderer/ENRMMathInlineRenderer.h +1 -1
- package/ios/renderer/ENRMMathInlineRenderer.m +5 -1
- package/ios/renderer/ENRMSpoilerRenderer.h +1 -1
- package/ios/renderer/ENRMSpoilerRenderer.m +3 -1
- package/ios/renderer/EmphasisRenderer.h +1 -1
- package/ios/renderer/EmphasisRenderer.m +3 -1
- package/ios/renderer/HeadingRenderer.h +1 -1
- package/ios/renderer/HeadingRenderer.m +13 -6
- package/ios/renderer/HighlightRenderer.h +1 -1
- package/ios/renderer/HighlightRenderer.m +3 -1
- package/ios/renderer/LinkRenderer.h +1 -1
- package/ios/renderer/LinkRenderer.m +3 -1
- package/ios/renderer/ListItemRenderer.h +13 -1
- package/ios/renderer/ListItemRenderer.m +102 -44
- package/ios/renderer/ListRenderer.h +2 -2
- package/ios/renderer/ListRenderer.m +63 -25
- package/ios/renderer/ParagraphRenderer.h +1 -1
- package/ios/renderer/ParagraphRenderer.m +16 -8
- package/ios/renderer/RenderContext.h +10 -0
- package/ios/renderer/RenderContext.m +44 -0
- package/ios/renderer/RendererFactory.m +14 -0
- package/ios/renderer/StrikethroughRenderer.h +1 -1
- package/ios/renderer/StrikethroughRenderer.m +3 -1
- package/ios/renderer/StrongRenderer.h +1 -1
- package/ios/renderer/StrongRenderer.m +3 -1
- package/ios/renderer/SubscriptRenderer.h +1 -1
- package/ios/renderer/SubscriptRenderer.m +3 -1
- package/ios/renderer/SuperscriptRenderer.h +1 -1
- package/ios/renderer/SuperscriptRenderer.m +3 -1
- package/ios/renderer/TextRenderer.h +2 -2
- package/ios/renderer/TextRenderer.m +3 -1
- package/ios/renderer/ThematicBreakRenderer.h +1 -1
- package/ios/renderer/ThematicBreakRenderer.m +3 -1
- package/ios/renderer/UnderlineRenderer.h +1 -1
- package/ios/renderer/UnderlineRenderer.m +3 -1
- package/ios/styles/StyleConfig.h +22 -0
- package/ios/styles/StyleConfig.mm +132 -0
- package/ios/utils/BlockquoteBorder.h +6 -0
- package/ios/utils/BlockquoteBorder.m +249 -52
- package/ios/utils/CodeBlockBackground.m +16 -2
- package/ios/utils/ENRMAtomicSize.h +65 -0
- package/ios/utils/ENRMBlockMenu.h +57 -0
- package/ios/utils/ENRMCodeBlockContent.h +37 -0
- package/ios/utils/ENRMCodeBlockContent.mm +79 -0
- package/ios/utils/ENRMCodeBlockHighlighter.h +37 -0
- package/ios/utils/ENRMCodeBlockHighlighter.mm +51 -0
- package/ios/utils/ENRMFeatureFlags.h +7 -0
- package/ios/utils/ENRMImageDownloader.h +11 -1
- package/ios/utils/ENRMImageDownloader.m +60 -16
- package/ios/utils/ENRMLocalImageLoader.h +31 -0
- package/ios/utils/ENRMLocalImageLoader.m +68 -0
- package/ios/utils/ENRMMathFallback.h +26 -0
- package/ios/utils/ENRMMathFallback.m +18 -0
- package/ios/utils/ENRMTextViewSetup.h +35 -17
- package/ios/utils/EditMenuUtils.h +22 -5
- package/ios/utils/EditMenuUtils.m +53 -9
- package/ios/utils/ImageRequestHeaderUtils.h +35 -0
- package/ios/utils/LastElementUtils.h +1 -0
- package/ios/utils/ListMarkerDrawer.m +29 -42
- package/ios/utils/MarkdownASTSerializer.m +4 -0
- package/ios/utils/ParagraphStyleUtils.h +5 -0
- package/ios/utils/ParagraphStyleUtils.m +77 -17
- package/ios/utils/RenderedMarkdownSegment.h +13 -1
- package/ios/utils/RenderedMarkdownSegment.m +20 -0
- package/ios/utils/SegmentRenderer.m +17 -4
- package/ios/utils/StreamingMarkdownFilter.h +11 -1
- package/ios/utils/StreamingMarkdownFilter.m +98 -2
- package/ios/utils/StylePropsUtils.h +63 -0
- package/ios/utils/TaskListTapUtils.m +24 -0
- package/ios/views/ENRMCodeBlockContainerView.h +53 -0
- package/ios/views/ENRMCodeBlockContainerView.m +559 -0
- package/ios/views/ENRMMathContainerView.h +16 -0
- package/ios/views/ENRMMathContainerView.m +74 -19
- package/ios/views/TableContainerView.h +22 -0
- package/ios/views/TableContainerView.m +261 -175
- package/jest.d.ts +1 -0
- package/jest.js +5 -0
- package/lib/module/EnrichedMarkdownNativeComponent.ts +73 -0
- package/lib/module/EnrichedMarkdownTextInput.js +84 -5
- package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
- package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
- package/lib/module/EnrichedMarkdownTextNativeComponent.ts +74 -0
- package/lib/module/headingDefaults.js +34 -0
- package/lib/module/headingDefaults.js.map +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/jest/index.js +191 -0
- package/lib/module/jest/index.js.map +1 -0
- package/lib/module/native/EnrichedMarkdownText.js +37 -5
- package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
- package/lib/module/normalizeMarkdownStyle.js +81 -19
- package/lib/module/normalizeMarkdownStyle.js.map +1 -1
- package/lib/module/normalizeMarkdownStyle.web.js +56 -18
- package/lib/module/normalizeMarkdownStyle.web.js.map +1 -1
- package/lib/module/normalizeMarkdownTextInputStyle.js +62 -15
- package/lib/module/normalizeMarkdownTextInputStyle.js.map +1 -1
- package/lib/module/normalizeMenuItem.js +1 -1
- package/lib/module/utils/textInputState.js +26 -0
- package/lib/module/utils/textInputState.js.map +1 -0
- package/lib/module/web/EnrichedMarkdownText.js +9 -5
- package/lib/module/web/EnrichedMarkdownText.js.map +1 -1
- package/lib/module/web/parseMarkdown.js +4 -3
- package/lib/module/web/parseMarkdown.js.map +1 -1
- package/lib/module/web/renderers/InlineRenderers.js +6 -0
- package/lib/module/web/renderers/InlineRenderers.js.map +1 -1
- package/lib/module/web/renderers/ListRenderers.js +7 -2
- package/lib/module/web/renderers/ListRenderers.js.map +1 -1
- package/lib/module/web/renderers/index.js +7 -4
- package/lib/module/web/renderers/index.js.map +1 -1
- package/lib/module/web/styles.js +83 -6
- package/lib/module/web/styles.js.map +1 -1
- package/lib/module/web/utils.js +1 -0
- package/lib/module/web/utils.js.map +1 -1
- package/lib/module/web/wasm/md4c.js +0 -0
- package/lib/module/web/wasm/md4c.js.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +66 -0
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +94 -9
- package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +69 -5
- package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +66 -0
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/headingDefaults.d.ts +9 -0
- package/lib/typescript/src/headingDefaults.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +2 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/index.web.d.ts +1 -1
- package/lib/typescript/src/index.web.d.ts.map +1 -1
- package/lib/typescript/src/jest/index.d.ts +6 -0
- package/lib/typescript/src/jest/index.d.ts.map +1 -0
- package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +3 -3
- package/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts +19 -5
- package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownStyle.d.ts +72 -0
- package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +27 -0
- package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownTextProps.d.ts +104 -9
- package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownTextProps.web.d.ts +19 -0
- package/lib/typescript/src/types/MarkdownTextProps.web.d.ts.map +1 -1
- package/lib/typescript/src/types/events.d.ts +19 -0
- package/lib/typescript/src/types/events.d.ts.map +1 -1
- package/lib/typescript/src/utils/textInputState.d.ts +24 -0
- package/lib/typescript/src/utils/textInputState.d.ts.map +1 -0
- package/lib/typescript/src/web/EnrichedMarkdownText.d.ts +1 -1
- package/lib/typescript/src/web/EnrichedMarkdownText.d.ts.map +1 -1
- package/lib/typescript/src/web/parseMarkdown.d.ts +1 -1
- package/lib/typescript/src/web/parseMarkdown.d.ts.map +1 -1
- package/lib/typescript/src/web/renderers/InlineRenderers.d.ts.map +1 -1
- package/lib/typescript/src/web/renderers/ListRenderers.d.ts.map +1 -1
- package/lib/typescript/src/web/renderers/index.d.ts +2 -1
- package/lib/typescript/src/web/renderers/index.d.ts.map +1 -1
- package/lib/typescript/src/web/styles.d.ts +2 -1
- package/lib/typescript/src/web/styles.d.ts.map +1 -1
- package/lib/typescript/src/web/types.d.ts +6 -2
- package/lib/typescript/src/web/types.d.ts.map +1 -1
- package/lib/typescript/src/web/utils.d.ts.map +1 -1
- package/package.json +36 -9
- package/postinstall.mjs +131 -0
- package/ratex-version.json +21 -0
- package/src/EnrichedMarkdownNativeComponent.ts +73 -0
- package/src/EnrichedMarkdownTextInput.tsx +159 -8
- package/src/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
- package/src/EnrichedMarkdownTextNativeComponent.ts +74 -0
- package/src/headingDefaults.ts +21 -0
- package/src/index.tsx +9 -0
- package/src/index.web.tsx +1 -0
- package/src/jest/index.tsx +215 -0
- package/src/native/EnrichedMarkdownText.tsx +53 -2
- package/src/normalizeMarkdownStyle.ts +102 -16
- package/src/normalizeMarkdownStyle.web.ts +63 -15
- package/src/normalizeMarkdownTextInputStyle.ts +110 -35
- package/src/normalizeMenuItem.ts +1 -1
- package/src/types/MarkdownStyle.ts +74 -0
- package/src/types/MarkdownStyleInternal.ts +39 -0
- package/src/types/MarkdownTextProps.ts +101 -9
- package/src/types/MarkdownTextProps.web.ts +19 -0
- package/src/types/events.ts +21 -0
- package/src/utils/textInputState.ts +35 -0
- package/src/web/EnrichedMarkdownText.tsx +16 -2
- package/src/web/parseMarkdown.ts +6 -2
- package/src/web/renderers/InlineRenderers.tsx +5 -0
- package/src/web/renderers/ListRenderers.tsx +14 -2
- package/src/web/renderers/index.tsx +6 -2
- package/src/web/styles.ts +89 -5
- package/src/web/types.ts +6 -1
- package/src/web/utils.ts +1 -0
- package/src/web/wasm/md4c.js +0 -0
- package/vendor-grammars.mjs +511 -0
- package/vendor-ratex.mjs +173 -0
- package/app.plugin.js +0 -2
- package/plugin/build/withAndroidMath.js +0 -19
- package/plugin/build/withIosMath.js +0 -28
- package/plugin/build/withReactNativeEnrichedMarkdown.js +0 -11
- package/plugin/src/withAndroidMath.ts +0 -24
- package/plugin/src/withIosMath.ts +0 -35
- package/plugin/src/withReactNativeEnrichedMarkdown.ts +0 -17
- package/plugin/tsconfig.build.json +0 -16
|
@@ -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;
|
|
234
|
-
|
|
239
|
+
_enableTaskListItemToggle = YES;
|
|
240
|
+
_forceHeightUpdateOnNextRender = NO;
|
|
241
|
+
_contextMenuHidden = NO;
|
|
242
|
+
_selectionMenuConfig = ENRMDefaultSelectionMenuConfig();
|
|
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) {
|
|
@@ -289,7 +301,8 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
289
301
|
selectionEnd:selectionEnd];
|
|
290
302
|
});
|
|
291
303
|
return buildEditMenuForSelection(textView.textStorage, textView.selectedRange, strongSelf->_cachedMarkdown,
|
|
292
|
-
strongSelf->_config, @[ baseMenu ], customItems,
|
|
304
|
+
strongSelf->_config, @[ baseMenu ], customItems,
|
|
305
|
+
strongSelf -> _selectionMenuConfig);
|
|
293
306
|
};
|
|
294
307
|
#endif
|
|
295
308
|
|
|
@@ -495,6 +508,11 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
495
508
|
_dirtyFlags |= ENRMDirtyRender;
|
|
496
509
|
}
|
|
497
510
|
|
|
511
|
+
if (ENRMImageRequestHeadersChanged(oldViewProps.imageRequestHeaders, newViewProps.imageRequestHeaders)) {
|
|
512
|
+
[_config setImageRequestHeaders:ENRMImageRequestHeadersFromProps(newViewProps.imageRequestHeaders)];
|
|
513
|
+
_dirtyFlags |= ENRMDirtyRender;
|
|
514
|
+
}
|
|
515
|
+
|
|
498
516
|
NSLayoutManager *layoutManager = _textView.layoutManager;
|
|
499
517
|
if ([layoutManager isKindOfClass:[TextViewLayoutManager class]]) {
|
|
500
518
|
StyleConfig *currentConfig = [layoutManager valueForKey:@"config"];
|
|
@@ -539,33 +557,20 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
539
557
|
_dirtyFlags |= ENRMDirtyRender;
|
|
540
558
|
}
|
|
541
559
|
|
|
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;
|
|
560
|
+
if (newViewProps.md4cFlags.underline != oldViewProps.md4cFlags.underline ||
|
|
561
|
+
newViewProps.md4cFlags.superscript != oldViewProps.md4cFlags.superscript ||
|
|
562
|
+
newViewProps.md4cFlags.subscript != oldViewProps.md4cFlags.subscript ||
|
|
563
|
+
newViewProps.md4cFlags.latexMath != oldViewProps.md4cFlags.latexMath ||
|
|
564
|
+
newViewProps.md4cFlags.highlight != oldViewProps.md4cFlags.highlight ||
|
|
565
|
+
newViewProps.md4cFlags.hardSoftBreaks != oldViewProps.md4cFlags.hardSoftBreaks) {
|
|
566
|
+
_md4cFlags = [EnrichedMarkdownText flagsFromProps:newViewProps.md4cFlags];
|
|
564
567
|
_forceHeightUpdateOnNextRender = YES;
|
|
565
568
|
_dirtyFlags |= ENRMDirtyRender;
|
|
566
569
|
}
|
|
567
570
|
|
|
568
571
|
_enableLinkPreview = newViewProps.enableLinkPreview;
|
|
572
|
+
_enableTaskListItemToggle = newViewProps.enableTaskListItemToggle;
|
|
573
|
+
_contextMenuHidden = newViewProps.contextMenuHidden;
|
|
569
574
|
|
|
570
575
|
if (ENRMContextMenuItemsChanged(oldViewProps.contextMenuItems, newViewProps.contextMenuItems)) {
|
|
571
576
|
_contextMenuItemTexts = ENRMContextMenuTextsFromItems(newViewProps.contextMenuItems);
|
|
@@ -573,9 +578,7 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
573
578
|
}
|
|
574
579
|
|
|
575
580
|
_selectionMenuLabels = ENRMParseSelectionMenuLabels(newViewProps.selectionMenuConfig);
|
|
576
|
-
_selectionMenuConfig =
|
|
577
|
-
ENRMBuildSelectionMenuConfig(_selectionMenuLabels, newViewProps.selectionMenuConfig.copyAsMarkdown,
|
|
578
|
-
newViewProps.selectionMenuConfig.copyImageUrl);
|
|
581
|
+
_selectionMenuConfig = ENRMBuildSelectionMenuConfig(_selectionMenuLabels, newViewProps.selectionMenuConfig);
|
|
579
582
|
|
|
580
583
|
if (ENRMAccessibilityLabelsChanged(oldViewProps.accessibilityLabels, newViewProps.accessibilityLabels)) {
|
|
581
584
|
_accessibilityLabels = [[ENRMAccessibilityLabels alloc] init];
|
|
@@ -665,26 +668,46 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
665
668
|
|
|
666
669
|
- (void)prepareForRecycle
|
|
667
670
|
{
|
|
668
|
-
|
|
671
|
+
const auto resetProps = std::make_shared<const EnrichedMarkdownTextProps>();
|
|
672
|
+
_props = resetProps;
|
|
669
673
|
[_renderCoordinator invalidate];
|
|
670
674
|
|
|
671
675
|
[_fadeAnimator cancel];
|
|
672
676
|
_fadeAnimator = nil;
|
|
673
677
|
_previousTextLength = 0;
|
|
678
|
+
_streamingAnimation = NO;
|
|
679
|
+
_forceHeightUpdateOnNextRender = NO;
|
|
674
680
|
_cachedMarkdown = nil;
|
|
675
681
|
_renderedMarkdown = nil;
|
|
682
|
+
_config = nil;
|
|
683
|
+
_md4cFlags = [EnrichedMarkdownText flagsFromProps:resetProps->md4cFlags];
|
|
684
|
+
_maxFontSizeMultiplier = 0;
|
|
685
|
+
_lastElementMarginBottom = 0;
|
|
686
|
+
_allowTrailingMargin = NO;
|
|
687
|
+
_lineBreakStrategy = NSLineBreakStrategyNone;
|
|
688
|
+
_writingDirectionMode = ENRMWritingDirectionModeFirstStrong;
|
|
689
|
+
_renderedStyleFingerprint = 0;
|
|
690
|
+
_pendingStyleFingerprint = 0;
|
|
691
|
+
_contextMenuItemTexts = nil;
|
|
692
|
+
_contextMenuItemIcons = nil;
|
|
693
|
+
_fontScaleObserver.allowFontScaling = resetProps->allowFontScaling;
|
|
694
|
+
_accessibilityLabels = nil;
|
|
676
695
|
_accessibilityElements = nil;
|
|
677
696
|
_accessibilityInfo = nil;
|
|
678
697
|
_accessibilityNeedsRebuild = NO;
|
|
679
698
|
[_spoilerManager removeAllOverlays];
|
|
680
|
-
|
|
681
|
-
[self resetPropDerivedState];
|
|
682
|
-
|
|
699
|
+
_spoilerManager = nil;
|
|
683
700
|
if (_textView != nil) {
|
|
684
701
|
ENRMSetAttributedText(_textView, [[NSAttributedString alloc] initWithString:@""]);
|
|
685
702
|
_textView.hidden = YES;
|
|
686
703
|
}
|
|
687
704
|
|
|
705
|
+
// Ported from the fork's resetPropDerivedState: upstream's prepareForRecycle covers every
|
|
706
|
+
// other prop-derived ivar but leaves these two, so a recycled view keeps the previous
|
|
707
|
+
// consumer's height-update counter and a dangling shadow-node state handle.
|
|
708
|
+
_heightUpdateCounter = 0;
|
|
709
|
+
_state = nullptr;
|
|
710
|
+
|
|
688
711
|
[super prepareForRecycle];
|
|
689
712
|
}
|
|
690
713
|
|
|
@@ -745,7 +768,8 @@ Class<RCTComponentViewProtocol> EnrichedMarkdownTextCls(void)
|
|
|
745
768
|
{
|
|
746
769
|
ENRMPlatformTextView *textView = (ENRMPlatformTextView *)recognizer.view;
|
|
747
770
|
|
|
748
|
-
if (
|
|
771
|
+
if (_enableTaskListItemToggle &&
|
|
772
|
+
handleTaskListTapWithSharedLogic(
|
|
749
773
|
textView, recognizer, &self->_cachedMarkdown, self->_config,
|
|
750
774
|
^(NSInteger index, BOOL checked, NSString *itemText) {
|
|
751
775
|
[self emitTaskListItemPress:index checked:checked text:itemText];
|
|
@@ -790,6 +814,10 @@ Class<RCTComponentViewProtocol> EnrichedMarkdownTextCls(void)
|
|
|
790
814
|
editMenuForTextInRange:(NSRange)range
|
|
791
815
|
suggestedActions:(NSArray<UIMenuElement *> *)suggestedActions API_AVAILABLE(ios(16.0))
|
|
792
816
|
{
|
|
817
|
+
if (_contextMenuHidden) {
|
|
818
|
+
return nil;
|
|
819
|
+
}
|
|
820
|
+
|
|
793
821
|
__weak EnrichedMarkdownText *weakSelf = self;
|
|
794
822
|
ENRMContextMenuPressHandler handler =
|
|
795
823
|
^(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
|
|