react-native-enriched-markdown 0.1.0 → 0.2.0
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/LICENSE +20 -0
- package/README.md +551 -0
- package/ReactNativeEnrichedMarkdown.podspec +27 -0
- package/android/build.gradle +101 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +54 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +26 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ComponentDescriptors.cpp +22 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ComponentDescriptors.h +24 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +33 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +31 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +82 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +1388 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ShadowNodes.cpp +17 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/ShadowNodes.h +32 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/States.cpp +16 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/States.h +20 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/baseline-prof.txt +65 -0
- package/android/src/main/cpp/jni-adapter.cpp +220 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +270 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextLayoutManager.kt +15 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +173 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextPackage.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +385 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/accessibility/MarkdownAccessibilityHelper.kt +279 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/events/LinkLongPressEvent.kt +23 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/events/LinkPressEvent.kt +23 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +31 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +62 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +166 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +84 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +104 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeRenderer.kt +36 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/DocumentRenderer.kt +16 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/EmphasisRenderer.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +70 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ImageRenderer.kt +68 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/LineBreakRenderer.kt +16 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt +29 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +105 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +59 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +76 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +103 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ParagraphRenderer.kt +80 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/Renderer.kt +109 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +86 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/StrikethroughRenderer.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/StrongRenderer.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/TextRenderer.kt +30 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ThematicBreakRenderer.kt +45 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/UnderlineRenderer.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +136 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +135 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +180 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +196 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +34 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/HeadingSpan.kt +38 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +321 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/LineHeightSpan.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt +51 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/MarginBottomSpan.kt +76 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +87 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrikethroughSpan.kt +12 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +37 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/TextSpan.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ThematicBreakSpan.kt +69 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +69 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/BaseBlockStyle.kt +11 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +51 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +54 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeStyle.kt +21 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/EmphasisStyle.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/HeadingStyle.kt +33 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +23 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/InlineImageStyle.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkStyle.kt +19 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +57 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ParagraphStyle.kt +33 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/StrikethroughStyle.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/StrongStyle.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +211 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleParser.kt +92 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/TextAlignment.kt +32 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ThematicBreakStyle.kt +23 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/UnderlineStyle.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/AsyncDrawable.kt +91 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/HTMLGenerator.kt +827 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/LinkLongPressMovementMethod.kt +121 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/MarkdownExtractor.kt +375 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/SelectionActionMode.kt +139 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/Utils.kt +183 -0
- package/android/src/main/jni/CMakeLists.txt +70 -0
- package/android/src/main/jni/EnrichedMarkdownTextSpec.cpp +21 -0
- package/android/src/main/jni/EnrichedMarkdownTextSpec.h +25 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextComponentDescriptor.h +29 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextMeasurementManager.cpp +45 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextMeasurementManager.h +21 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +20 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +37 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +22 -0
- package/cpp/md4c/md4c.c +6492 -0
- package/cpp/md4c/md4c.h +402 -0
- package/cpp/parser/MD4CParser.cpp +327 -0
- package/cpp/parser/MD4CParser.hpp +27 -0
- package/cpp/parser/MarkdownASTNode.hpp +51 -0
- package/ios/EnrichedMarkdownText.h +18 -0
- package/ios/EnrichedMarkdownText.mm +1401 -0
- package/ios/attachments/EnrichedMarkdownImageAttachment.h +23 -0
- package/ios/attachments/EnrichedMarkdownImageAttachment.m +185 -0
- package/ios/attachments/ThematicBreakAttachment.h +15 -0
- package/ios/attachments/ThematicBreakAttachment.m +33 -0
- package/ios/generated/EnrichedMarkdownTextSpec/ComponentDescriptors.cpp +22 -0
- package/ios/generated/EnrichedMarkdownTextSpec/ComponentDescriptors.h +24 -0
- package/ios/generated/EnrichedMarkdownTextSpec/EventEmitters.cpp +33 -0
- package/ios/generated/EnrichedMarkdownTextSpec/EventEmitters.h +31 -0
- package/ios/generated/EnrichedMarkdownTextSpec/Props.cpp +82 -0
- package/ios/generated/EnrichedMarkdownTextSpec/Props.h +1388 -0
- package/ios/generated/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +20 -0
- package/ios/generated/EnrichedMarkdownTextSpec/ShadowNodes.cpp +17 -0
- package/ios/generated/EnrichedMarkdownTextSpec/ShadowNodes.h +32 -0
- package/ios/generated/EnrichedMarkdownTextSpec/States.cpp +16 -0
- package/ios/generated/EnrichedMarkdownTextSpec/States.h +20 -0
- package/ios/internals/EnrichedMarkdownTextComponentDescriptor.h +19 -0
- package/ios/internals/EnrichedMarkdownTextShadowNode.h +43 -0
- package/ios/internals/EnrichedMarkdownTextShadowNode.mm +85 -0
- package/ios/internals/EnrichedMarkdownTextState.h +24 -0
- package/ios/parser/MarkdownASTNode.h +35 -0
- package/ios/parser/MarkdownASTNode.m +32 -0
- package/ios/parser/MarkdownParser.h +17 -0
- package/ios/parser/MarkdownParser.mm +42 -0
- package/ios/parser/MarkdownParserBridge.mm +120 -0
- package/ios/renderer/AttributedRenderer.h +11 -0
- package/ios/renderer/AttributedRenderer.m +152 -0
- package/ios/renderer/BlockquoteRenderer.h +7 -0
- package/ios/renderer/BlockquoteRenderer.m +160 -0
- package/ios/renderer/CodeBlockRenderer.h +10 -0
- package/ios/renderer/CodeBlockRenderer.m +90 -0
- package/ios/renderer/CodeRenderer.h +10 -0
- package/ios/renderer/CodeRenderer.m +60 -0
- package/ios/renderer/EmphasisRenderer.h +6 -0
- package/ios/renderer/EmphasisRenderer.m +96 -0
- package/ios/renderer/HeadingRenderer.h +7 -0
- package/ios/renderer/HeadingRenderer.m +105 -0
- package/ios/renderer/ImageRenderer.h +12 -0
- package/ios/renderer/ImageRenderer.m +83 -0
- package/ios/renderer/LinkRenderer.h +7 -0
- package/ios/renderer/LinkRenderer.m +69 -0
- package/ios/renderer/ListItemRenderer.h +16 -0
- package/ios/renderer/ListItemRenderer.m +103 -0
- package/ios/renderer/ListRenderer.h +13 -0
- package/ios/renderer/ListRenderer.m +70 -0
- package/ios/renderer/NodeRenderer.h +8 -0
- package/ios/renderer/ParagraphRenderer.h +7 -0
- package/ios/renderer/ParagraphRenderer.m +80 -0
- package/ios/renderer/RenderContext.h +105 -0
- package/ios/renderer/RenderContext.m +312 -0
- package/ios/renderer/RendererFactory.h +12 -0
- package/ios/renderer/RendererFactory.m +116 -0
- package/ios/renderer/StrikethroughRenderer.h +6 -0
- package/ios/renderer/StrikethroughRenderer.m +40 -0
- package/ios/renderer/StrongRenderer.h +6 -0
- package/ios/renderer/StrongRenderer.m +83 -0
- package/ios/renderer/TextRenderer.h +6 -0
- package/ios/renderer/TextRenderer.m +16 -0
- package/ios/renderer/ThematicBreakRenderer.h +5 -0
- package/ios/renderer/ThematicBreakRenderer.m +53 -0
- package/ios/renderer/UnderlineRenderer.h +6 -0
- package/ios/renderer/UnderlineRenderer.m +39 -0
- package/ios/styles/StyleConfig.h +274 -0
- package/ios/styles/StyleConfig.mm +1806 -0
- package/ios/utils/AccessibilityInfo.h +35 -0
- package/ios/utils/AccessibilityInfo.m +24 -0
- package/ios/utils/BlockquoteBorder.h +20 -0
- package/ios/utils/BlockquoteBorder.m +92 -0
- package/ios/utils/CodeBackground.h +19 -0
- package/ios/utils/CodeBackground.m +191 -0
- package/ios/utils/CodeBlockBackground.h +17 -0
- package/ios/utils/CodeBlockBackground.m +82 -0
- package/ios/utils/EditMenuUtils.h +22 -0
- package/ios/utils/EditMenuUtils.m +118 -0
- package/ios/utils/FontUtils.h +25 -0
- package/ios/utils/FontUtils.m +27 -0
- package/ios/utils/HTMLGenerator.h +20 -0
- package/ios/utils/HTMLGenerator.m +793 -0
- package/ios/utils/LastElementUtils.h +53 -0
- package/ios/utils/ListMarkerDrawer.h +15 -0
- package/ios/utils/ListMarkerDrawer.m +127 -0
- package/ios/utils/MarkdownAccessibilityElementBuilder.h +45 -0
- package/ios/utils/MarkdownAccessibilityElementBuilder.m +323 -0
- package/ios/utils/MarkdownExtractor.h +17 -0
- package/ios/utils/MarkdownExtractor.m +308 -0
- package/ios/utils/ParagraphStyleUtils.h +21 -0
- package/ios/utils/ParagraphStyleUtils.m +111 -0
- package/ios/utils/PasteboardUtils.h +36 -0
- package/ios/utils/PasteboardUtils.m +134 -0
- package/ios/utils/RTFExportUtils.h +24 -0
- package/ios/utils/RTFExportUtils.m +297 -0
- package/ios/utils/RuntimeKeys.h +38 -0
- package/ios/utils/RuntimeKeys.m +11 -0
- package/ios/utils/TextViewLayoutManager.h +14 -0
- package/ios/utils/TextViewLayoutManager.mm +113 -0
- package/lib/module/EnrichedMarkdownText.js +65 -0
- package/lib/module/EnrichedMarkdownText.js.map +1 -0
- package/lib/module/EnrichedMarkdownTextNativeComponent.ts +210 -0
- package/lib/module/index.js +4 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/normalizeMarkdownStyle.js +384 -0
- package/lib/module/normalizeMarkdownStyle.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/EnrichedMarkdownText.d.ts +183 -0
- package/lib/typescript/src/EnrichedMarkdownText.d.ts.map +1 -0
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +185 -0
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +4 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/normalizeMarkdownStyle.d.ts +6 -0
- package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -0
- package/package.json +186 -1
- package/react-native.config.js +13 -0
- package/src/EnrichedMarkdownText.tsx +280 -0
- package/src/EnrichedMarkdownTextNativeComponent.ts +210 -0
- package/src/index.tsx +10 -0
- package/src/normalizeMarkdownStyle.ts +423 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#import <UIKit/UIKit.h>
|
|
3
|
+
|
|
4
|
+
@class StyleConfig;
|
|
5
|
+
@class UITextView;
|
|
6
|
+
|
|
7
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Custom NSTextAttachment for rendering markdown images.
|
|
11
|
+
* Images are loaded asynchronously and scaled dynamically based on text container width.
|
|
12
|
+
* Supports inline and block images with custom height and border radius from config.
|
|
13
|
+
*/
|
|
14
|
+
@interface EnrichedMarkdownImageAttachment : NSTextAttachment
|
|
15
|
+
|
|
16
|
+
@property (nonatomic, readonly) NSString *imageURL;
|
|
17
|
+
@property (nonatomic, readonly) BOOL isInline;
|
|
18
|
+
|
|
19
|
+
- (instancetype)initWithImageURL:(NSString *)imageURL config:(StyleConfig *)config isInline:(BOOL)isInline;
|
|
20
|
+
|
|
21
|
+
@end
|
|
22
|
+
|
|
23
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
#import "EnrichedMarkdownImageAttachment.h"
|
|
2
|
+
#import "RuntimeKeys.h"
|
|
3
|
+
#import "StyleConfig.h"
|
|
4
|
+
#import <React/RCTLog.h>
|
|
5
|
+
#import <objc/runtime.h>
|
|
6
|
+
|
|
7
|
+
@interface EnrichedMarkdownImageAttachment ()
|
|
8
|
+
@property (nonatomic, readwrite) NSString *imageURL;
|
|
9
|
+
@property (nonatomic, weak) StyleConfig *config;
|
|
10
|
+
@property (nonatomic, assign) BOOL isInline;
|
|
11
|
+
@property (nonatomic, assign) CGFloat cachedHeight;
|
|
12
|
+
@property (nonatomic, assign) CGFloat cachedBorderRadius;
|
|
13
|
+
@property (nonatomic, weak) NSTextContainer *textContainer;
|
|
14
|
+
@property (nonatomic, weak) UITextView *textView;
|
|
15
|
+
@property (nonatomic, strong) UIImage *originalImage;
|
|
16
|
+
@property (nonatomic, strong) UIImage *loadedImage;
|
|
17
|
+
@property (nonatomic, strong) NSURLSessionDataTask *loadingTask;
|
|
18
|
+
@end
|
|
19
|
+
|
|
20
|
+
@implementation EnrichedMarkdownImageAttachment
|
|
21
|
+
|
|
22
|
+
- (instancetype)initWithImageURL:(NSString *)imageURL config:(StyleConfig *)config isInline:(BOOL)isInline
|
|
23
|
+
{
|
|
24
|
+
if (self = [super init]) {
|
|
25
|
+
_imageURL = imageURL;
|
|
26
|
+
_config = config;
|
|
27
|
+
_isInline = isInline;
|
|
28
|
+
_cachedHeight = isInline ? [config inlineImageSize] : [config imageHeight];
|
|
29
|
+
_cachedBorderRadius = [config imageBorderRadius];
|
|
30
|
+
|
|
31
|
+
[self setupPlaceholder];
|
|
32
|
+
[self loadImage];
|
|
33
|
+
}
|
|
34
|
+
return self;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer
|
|
38
|
+
proposedLineFragment:(CGRect)lineFrag
|
|
39
|
+
glyphPosition:(CGPoint)position
|
|
40
|
+
characterIndex:(NSUInteger)charIndex
|
|
41
|
+
{
|
|
42
|
+
CGFloat height = self.cachedHeight;
|
|
43
|
+
CGFloat width = self.isInline ? height : (lineFrag.size.width > 0 ? lineFrag.size.width : height);
|
|
44
|
+
return CGRectMake(0, 0, width, height);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
- (UIImage *)imageForBounds:(CGRect)imageBounds
|
|
48
|
+
textContainer:(NSTextContainer *)textContainer
|
|
49
|
+
characterIndex:(NSUInteger)charIndex
|
|
50
|
+
{
|
|
51
|
+
self.textContainer = textContainer;
|
|
52
|
+
|
|
53
|
+
// If width is now known but we haven't scaled yet, trigger it
|
|
54
|
+
if (self.originalImage && !self.loadedImage && imageBounds.size.width > 0) {
|
|
55
|
+
self.bounds = imageBounds;
|
|
56
|
+
[self handleLoadedImage:self.originalImage];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return self.loadedImage ?: self.image;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
- (void)handleLoadedImage:(UIImage *)image
|
|
63
|
+
{
|
|
64
|
+
if (!image)
|
|
65
|
+
return;
|
|
66
|
+
self.originalImage = image;
|
|
67
|
+
|
|
68
|
+
__weak typeof(self) weakSelf = self;
|
|
69
|
+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
70
|
+
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
71
|
+
if (!strongSelf)
|
|
72
|
+
return;
|
|
73
|
+
|
|
74
|
+
CGFloat targetWidth = strongSelf.isInline ? strongSelf.cachedHeight : strongSelf.bounds.size.width;
|
|
75
|
+
if (targetWidth <= 0)
|
|
76
|
+
return;
|
|
77
|
+
|
|
78
|
+
UIImage *scaled = [strongSelf scaleImage:image
|
|
79
|
+
toWidth:targetWidth
|
|
80
|
+
height:strongSelf.cachedHeight
|
|
81
|
+
borderRadius:strongSelf.cachedBorderRadius];
|
|
82
|
+
|
|
83
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
84
|
+
strongSelf.loadedImage = scaled;
|
|
85
|
+
|
|
86
|
+
if (strongSelf.isInline) {
|
|
87
|
+
// Use scaled image for RTF export (RTF uses self.image dimensions)
|
|
88
|
+
strongSelf.image = scaled;
|
|
89
|
+
strongSelf.bounds = CGRectMake(0, 0, strongSelf.cachedHeight, strongSelf.cachedHeight);
|
|
90
|
+
} else {
|
|
91
|
+
// Use original for "Save to Camera Roll" (no baked-in rounded corners)
|
|
92
|
+
strongSelf.image = image;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
[strongSelf updateUI];
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
- (void)updateUI
|
|
101
|
+
{
|
|
102
|
+
UITextView *textView = [self getTextView];
|
|
103
|
+
if (!textView)
|
|
104
|
+
return;
|
|
105
|
+
|
|
106
|
+
NSRange range = [self findAttachmentRangeInText:textView.attributedText];
|
|
107
|
+
if (range.location == NSNotFound)
|
|
108
|
+
return;
|
|
109
|
+
|
|
110
|
+
[textView.layoutManager invalidateDisplayForCharacterRange:range];
|
|
111
|
+
if (!self.isInline) {
|
|
112
|
+
[textView.layoutManager invalidateLayoutForCharacterRange:range actualCharacterRange:NULL];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
- (UITextView *)getTextView
|
|
117
|
+
{
|
|
118
|
+
if (self.textView)
|
|
119
|
+
return self.textView;
|
|
120
|
+
if (!self.textContainer)
|
|
121
|
+
return nil;
|
|
122
|
+
self.textView = objc_getAssociatedObject(self.textContainer, kTextViewKey);
|
|
123
|
+
return self.textView;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
- (void)setupPlaceholder
|
|
127
|
+
{
|
|
128
|
+
CGFloat size = self.cachedHeight;
|
|
129
|
+
self.bounds = CGRectMake(0, 0, size, size);
|
|
130
|
+
UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:CGSizeMake(size, size)];
|
|
131
|
+
self.image = [renderer imageWithActions:^(UIGraphicsImageRendererContext *ctx){}];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
- (void)loadImage
|
|
135
|
+
{
|
|
136
|
+
if (self.imageURL.length == 0)
|
|
137
|
+
return;
|
|
138
|
+
NSURL *url = [NSURL URLWithString:self.imageURL];
|
|
139
|
+
if (!url)
|
|
140
|
+
return;
|
|
141
|
+
|
|
142
|
+
__weak typeof(self) weakSelf = self;
|
|
143
|
+
self.loadingTask =
|
|
144
|
+
[[NSURLSession sharedSession] dataTaskWithURL:url
|
|
145
|
+
completionHandler:^(NSData *data, NSURLResponse *res, NSError *err) {
|
|
146
|
+
if (data) {
|
|
147
|
+
UIImage *img = [UIImage imageWithData:data];
|
|
148
|
+
dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf handleLoadedImage:img]; });
|
|
149
|
+
}
|
|
150
|
+
}];
|
|
151
|
+
[self.loadingTask resume];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
- (UIImage *)scaleImage:(UIImage *)image toWidth:(CGFloat)w height:(CGFloat)h borderRadius:(CGFloat)r
|
|
155
|
+
{
|
|
156
|
+
UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:CGSizeMake(w, h)];
|
|
157
|
+
return [renderer imageWithActions:^(UIGraphicsImageRendererContext *ctx) {
|
|
158
|
+
if (r > 0) {
|
|
159
|
+
[[UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, w, h) cornerRadius:r] addClip];
|
|
160
|
+
}
|
|
161
|
+
[image drawInRect:CGRectMake(0, 0, w, h)];
|
|
162
|
+
}];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
- (NSRange)findAttachmentRangeInText:(NSAttributedString *)text
|
|
166
|
+
{
|
|
167
|
+
__block NSRange found = NSMakeRange(NSNotFound, 0);
|
|
168
|
+
[text enumerateAttribute:NSAttachmentAttributeName
|
|
169
|
+
inRange:NSMakeRange(0, text.length)
|
|
170
|
+
options:0
|
|
171
|
+
usingBlock:^(id val, NSRange range, BOOL *stop) {
|
|
172
|
+
if (val == self) {
|
|
173
|
+
found = range;
|
|
174
|
+
*stop = YES;
|
|
175
|
+
}
|
|
176
|
+
}];
|
|
177
|
+
return found;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
- (void)dealloc
|
|
181
|
+
{
|
|
182
|
+
[_loadingTask cancel];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
@end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#import <UIKit/UIKit.h>
|
|
3
|
+
|
|
4
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
5
|
+
|
|
6
|
+
@interface ThematicBreakAttachment : NSTextAttachment
|
|
7
|
+
|
|
8
|
+
@property (nonatomic, strong) UIColor *lineColor;
|
|
9
|
+
@property (nonatomic, assign) CGFloat lineHeight;
|
|
10
|
+
@property (nonatomic, assign) CGFloat marginTop;
|
|
11
|
+
@property (nonatomic, assign) CGFloat marginBottom;
|
|
12
|
+
|
|
13
|
+
@end
|
|
14
|
+
|
|
15
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#import "ThematicBreakAttachment.h"
|
|
2
|
+
|
|
3
|
+
@implementation ThematicBreakAttachment
|
|
4
|
+
|
|
5
|
+
- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer
|
|
6
|
+
proposedLineFragment:(CGRect)lineFrag
|
|
7
|
+
glyphPosition:(CGPoint)position
|
|
8
|
+
characterIndex:(NSUInteger)charIndex
|
|
9
|
+
{
|
|
10
|
+
CGFloat totalHeight = self.marginTop + self.lineHeight + self.marginBottom;
|
|
11
|
+
return CGRectMake(0, 0, CGRectGetWidth(lineFrag), totalHeight);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
- (UIImage *)imageForBounds:(CGRect)imageBounds
|
|
15
|
+
textContainer:(NSTextContainer *)textContainer
|
|
16
|
+
characterIndex:(NSUInteger)charIndex
|
|
17
|
+
{
|
|
18
|
+
UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:imageBounds.size];
|
|
19
|
+
|
|
20
|
+
return [renderer imageWithActions:^(UIGraphicsImageRendererContext *_Nonnull rendererContext) {
|
|
21
|
+
CGContextRef ctx = rendererContext.CGContext;
|
|
22
|
+
|
|
23
|
+
CGFloat lineY = self.marginTop + (self.lineHeight / 2.0);
|
|
24
|
+
|
|
25
|
+
[self.lineColor setStroke];
|
|
26
|
+
CGContextSetLineWidth(ctx, self.lineHeight);
|
|
27
|
+
CGContextMoveToPoint(ctx, 0, lineY);
|
|
28
|
+
CGContextAddLineToPoint(ctx, imageBounds.size.width, lineY);
|
|
29
|
+
CGContextStrokePath(ctx);
|
|
30
|
+
}];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
|
4
|
+
*
|
|
5
|
+
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
|
6
|
+
* once the code is regenerated.
|
|
7
|
+
*
|
|
8
|
+
* @generated by codegen project: GenerateComponentDescriptorCpp.js
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#include "ComponentDescriptors.h"
|
|
12
|
+
#include <react/renderer/core/ConcreteComponentDescriptor.h>
|
|
13
|
+
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
|
|
14
|
+
|
|
15
|
+
namespace facebook::react {
|
|
16
|
+
|
|
17
|
+
void EnrichedMarkdownTextSpec_registerComponentDescriptorsFromCodegen(
|
|
18
|
+
std::shared_ptr<const ComponentDescriptorProviderRegistry> registry) {
|
|
19
|
+
registry->add(concreteComponentDescriptorProvider<EnrichedMarkdownTextComponentDescriptor>());
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
|
4
|
+
*
|
|
5
|
+
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
|
6
|
+
* once the code is regenerated.
|
|
7
|
+
*
|
|
8
|
+
* @generated by codegen project: GenerateComponentDescriptorH.js
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#pragma once
|
|
12
|
+
|
|
13
|
+
#include "ShadowNodes.h"
|
|
14
|
+
#include <react/renderer/core/ConcreteComponentDescriptor.h>
|
|
15
|
+
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
|
|
16
|
+
|
|
17
|
+
namespace facebook::react {
|
|
18
|
+
|
|
19
|
+
using EnrichedMarkdownTextComponentDescriptor = ConcreteComponentDescriptor<EnrichedMarkdownTextShadowNode>;
|
|
20
|
+
|
|
21
|
+
void EnrichedMarkdownTextSpec_registerComponentDescriptorsFromCodegen(
|
|
22
|
+
std::shared_ptr<const ComponentDescriptorProviderRegistry> registry);
|
|
23
|
+
|
|
24
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
|
4
|
+
*
|
|
5
|
+
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
|
6
|
+
* once the code is regenerated.
|
|
7
|
+
*
|
|
8
|
+
* @generated by codegen project: GenerateEventEmitterCpp.js
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#include "EventEmitters.h"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
namespace facebook::react {
|
|
15
|
+
|
|
16
|
+
void EnrichedMarkdownTextEventEmitter::onLinkPress(OnLinkPress event) const {
|
|
17
|
+
dispatchEvent("linkPress", [event=std::move(event)](jsi::Runtime &runtime) {
|
|
18
|
+
auto payload = jsi::Object(runtime);
|
|
19
|
+
payload.setProperty(runtime, "url", event.url);
|
|
20
|
+
return payload;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
void EnrichedMarkdownTextEventEmitter::onLinkLongPress(OnLinkLongPress event) const {
|
|
26
|
+
dispatchEvent("linkLongPress", [event=std::move(event)](jsi::Runtime &runtime) {
|
|
27
|
+
auto payload = jsi::Object(runtime);
|
|
28
|
+
payload.setProperty(runtime, "url", event.url);
|
|
29
|
+
return payload;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
|
4
|
+
*
|
|
5
|
+
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
|
6
|
+
* once the code is regenerated.
|
|
7
|
+
*
|
|
8
|
+
* @generated by codegen project: GenerateEventEmitterH.js
|
|
9
|
+
*/
|
|
10
|
+
#pragma once
|
|
11
|
+
|
|
12
|
+
#include <react/renderer/components/view/ViewEventEmitter.h>
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
namespace facebook::react {
|
|
16
|
+
class EnrichedMarkdownTextEventEmitter : public ViewEventEmitter {
|
|
17
|
+
public:
|
|
18
|
+
using ViewEventEmitter::ViewEventEmitter;
|
|
19
|
+
|
|
20
|
+
struct OnLinkPress {
|
|
21
|
+
std::string url;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
struct OnLinkLongPress {
|
|
25
|
+
std::string url;
|
|
26
|
+
};
|
|
27
|
+
void onLinkPress(OnLinkPress value) const;
|
|
28
|
+
|
|
29
|
+
void onLinkLongPress(OnLinkLongPress value) const;
|
|
30
|
+
};
|
|
31
|
+
} // namespace facebook::react
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
|
4
|
+
*
|
|
5
|
+
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
|
6
|
+
* once the code is regenerated.
|
|
7
|
+
*
|
|
8
|
+
* @generated by codegen project: GeneratePropsCpp.js
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#include "Props.h"
|
|
12
|
+
#include <react/renderer/core/PropsParserContext.h>
|
|
13
|
+
#include <react/renderer/core/propsConversions.h>
|
|
14
|
+
|
|
15
|
+
namespace facebook::react {
|
|
16
|
+
|
|
17
|
+
EnrichedMarkdownTextProps::EnrichedMarkdownTextProps(
|
|
18
|
+
const PropsParserContext &context,
|
|
19
|
+
const EnrichedMarkdownTextProps &sourceProps,
|
|
20
|
+
const RawProps &rawProps): ViewProps(context, sourceProps, rawProps),
|
|
21
|
+
|
|
22
|
+
markdown(convertRawProp(context, rawProps, "markdown", sourceProps.markdown, {})),
|
|
23
|
+
markdownStyle(convertRawProp(context, rawProps, "markdownStyle", sourceProps.markdownStyle, {})),
|
|
24
|
+
enableLinkPreview(convertRawProp(context, rawProps, "enableLinkPreview", sourceProps.enableLinkPreview, {true})),
|
|
25
|
+
selectable(convertRawProp(context, rawProps, "selectable", sourceProps.selectable, {false})),
|
|
26
|
+
md4cFlags(convertRawProp(context, rawProps, "md4cFlags", sourceProps.md4cFlags, {})),
|
|
27
|
+
allowFontScaling(convertRawProp(context, rawProps, "allowFontScaling", sourceProps.allowFontScaling, {true})),
|
|
28
|
+
maxFontSizeMultiplier(convertRawProp(context, rawProps, "maxFontSizeMultiplier", sourceProps.maxFontSizeMultiplier, {0.0})),
|
|
29
|
+
allowTrailingMargin(convertRawProp(context, rawProps, "allowTrailingMargin", sourceProps.allowTrailingMargin, {false})) {}
|
|
30
|
+
|
|
31
|
+
#ifdef RN_SERIALIZABLE_STATE
|
|
32
|
+
ComponentName EnrichedMarkdownTextProps::getDiffPropsImplementationTarget() const {
|
|
33
|
+
return "EnrichedMarkdownText";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
folly::dynamic EnrichedMarkdownTextProps::getDiffProps(
|
|
37
|
+
const Props* prevProps) const {
|
|
38
|
+
static const auto defaultProps = EnrichedMarkdownTextProps();
|
|
39
|
+
const EnrichedMarkdownTextProps* oldProps = prevProps == nullptr
|
|
40
|
+
? &defaultProps
|
|
41
|
+
: static_cast<const EnrichedMarkdownTextProps*>(prevProps);
|
|
42
|
+
if (this == oldProps) {
|
|
43
|
+
return folly::dynamic::object();
|
|
44
|
+
}
|
|
45
|
+
folly::dynamic result = HostPlatformViewProps::getDiffProps(prevProps);
|
|
46
|
+
|
|
47
|
+
if (markdown != oldProps->markdown) {
|
|
48
|
+
result["markdown"] = markdown;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (markdownStyle != oldProps->markdownStyle) {
|
|
52
|
+
result["markdownStyle"] = toDynamic(markdownStyle);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (enableLinkPreview != oldProps->enableLinkPreview) {
|
|
56
|
+
result["enableLinkPreview"] = enableLinkPreview;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (selectable != oldProps->selectable) {
|
|
60
|
+
result["selectable"] = selectable;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (md4cFlags != oldProps->md4cFlags) {
|
|
64
|
+
result["md4cFlags"] = toDynamic(md4cFlags);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (allowFontScaling != oldProps->allowFontScaling) {
|
|
68
|
+
result["allowFontScaling"] = allowFontScaling;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if ((maxFontSizeMultiplier != oldProps->maxFontSizeMultiplier) && !(std::isnan(maxFontSizeMultiplier) && std::isnan(oldProps->maxFontSizeMultiplier))) {
|
|
72
|
+
result["maxFontSizeMultiplier"] = maxFontSizeMultiplier;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (allowTrailingMargin != oldProps->allowTrailingMargin) {
|
|
76
|
+
result["allowTrailingMargin"] = allowTrailingMargin;
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
#endif
|
|
81
|
+
|
|
82
|
+
} // namespace facebook::react
|