react-native-jet-markdown 0.2.0-beta.7
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/JetMarkdown.podspec +42 -0
- package/LICENSE +20 -0
- package/README.md +247 -0
- package/android/CMakeLists.txt +52 -0
- package/android/build.gradle +55 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/JniBindings.cpp +243 -0
- package/android/src/main/java/com/jetmarkdown/JetMarkdownNative.kt +114 -0
- package/android/src/main/java/com/jetmarkdown/JetMarkdownPackage.kt +22 -0
- package/android/src/main/java/com/jetmarkdown/JetMarkdownView.kt +235 -0
- package/android/src/main/java/com/jetmarkdown/JetMarkdownViewManager.kt +75 -0
- package/android/src/main/java/com/jetmarkdown/editor/EditorSpans.kt +217 -0
- package/android/src/main/java/com/jetmarkdown/editor/JetMarkdownEditorManager.kt +224 -0
- package/android/src/main/java/com/jetmarkdown/editor/JetMarkdownEditorView.kt +1736 -0
- package/android/src/main/java/com/jetmarkdown/measure/MarkdownMeasurer.kt +54 -0
- package/android/src/main/java/com/jetmarkdown/parser/AstDecoder.kt +59 -0
- package/android/src/main/java/com/jetmarkdown/parser/MdNode.kt +43 -0
- package/android/src/main/java/com/jetmarkdown/render/ContentCache.kt +53 -0
- package/android/src/main/java/com/jetmarkdown/render/RenderedContent.kt +318 -0
- package/android/src/main/java/com/jetmarkdown/render/SpannableRenderer.kt +658 -0
- package/android/src/main/java/com/jetmarkdown/render/spans/ChipSpan.kt +17 -0
- package/android/src/main/java/com/jetmarkdown/render/spans/InteractiveSpans.kt +11 -0
- package/android/src/main/java/com/jetmarkdown/render/spans/MarkdownLineHeightSpan.kt +59 -0
- package/android/src/main/java/com/jetmarkdown/render/spans/RunSpan.kt +40 -0
- package/android/src/main/java/com/jetmarkdown/style/Fonts.kt +34 -0
- package/android/src/main/java/com/jetmarkdown/style/LayoutStyleSpec.kt +71 -0
- package/android/src/main/java/com/jetmarkdown/style/PlatformColorResolver.kt +77 -0
- package/android/src/main/java/com/jetmarkdown/style/StyleConfig.kt +80 -0
- package/android/src/main/java/com/jetmarkdown/style/TextStyleSpec.kt +61 -0
- package/android/src/main/java/com/jetmarkdown/views/BlockStackView.kt +292 -0
- package/android/src/main/java/com/jetmarkdown/views/BlockTextView.kt +378 -0
- package/android/src/main/java/com/jetmarkdown/views/BoxDrawing.kt +50 -0
- package/android/src/main/java/com/jetmarkdown/views/MarkdownHost.kt +12 -0
- package/android/src/main/java/com/jetmarkdown/views/MarkdownImageView.kt +113 -0
- package/android/src/main/java/com/jetmarkdown/views/NestedHorizontalScrollView.kt +87 -0
- package/android/src/main/java/com/jetmarkdown/views/TableBlockView.kt +139 -0
- package/cpp/core/Ast.h +85 -0
- package/cpp/core/AstJson.cpp +129 -0
- package/cpp/core/AstJson.h +12 -0
- package/cpp/core/AstSerializer.cpp +40 -0
- package/cpp/core/AstSerializer.h +21 -0
- package/cpp/core/AstToMarkdown.cpp +549 -0
- package/cpp/core/AstToMarkdown.h +16 -0
- package/cpp/core/EditorRuns.cpp +640 -0
- package/cpp/core/EditorRuns.h +94 -0
- package/cpp/core/EditorText.cpp +15 -0
- package/cpp/core/EditorText.h +18 -0
- package/cpp/core/InlineExtensions.cpp +305 -0
- package/cpp/core/InlineExtensions.h +17 -0
- package/cpp/core/Parser.cpp +470 -0
- package/cpp/core/Parser.h +16 -0
- package/cpp/core/Preprocess.cpp +181 -0
- package/cpp/core/Preprocess.h +14 -0
- package/cpp/md4c/LICENSE +22 -0
- package/cpp/md4c/VERSION +1 -0
- package/cpp/md4c/md4c.c +6462 -0
- package/cpp/md4c/md4c.h +407 -0
- package/cpp/react/JetMarkdownEditorShadowNode.cpp +54 -0
- package/cpp/react/JetMarkdownEditorShadowNode.h +55 -0
- package/cpp/react/JetMarkdownEditorState.h +35 -0
- package/cpp/react/JetMarkdownMeasurer.cpp +32 -0
- package/cpp/react/JetMarkdownMeasurer.h +41 -0
- package/cpp/react/JetMarkdownShadowNode.cpp +100 -0
- package/cpp/react/JetMarkdownShadowNode.h +53 -0
- package/cpp/react/JetMarkdownState.h +52 -0
- package/cpp/react/override/react/renderer/components/JetMarkdownViewSpec/ComponentDescriptors.h +21 -0
- package/cpp/tests/parser_tests.cpp +662 -0
- package/cpp/tests/run_tests.sh +25 -0
- package/ios/JetMarkdownView.h +14 -0
- package/ios/JetMarkdownView.mm +468 -0
- package/ios/editor/JetMarkdownEditor.h +12 -0
- package/ios/editor/JetMarkdownEditor.mm +2002 -0
- package/ios/measure/JMDMarkdownMeasurer.h +22 -0
- package/ios/measure/JMDMarkdownMeasurer.mm +38 -0
- package/ios/render/JMDBlock.h +97 -0
- package/ios/render/JMDBlock.m +28 -0
- package/ios/render/JMDBlockRenderer.h +17 -0
- package/ios/render/JMDBlockRenderer.mm +852 -0
- package/ios/render/JMDContentCache.h +17 -0
- package/ios/render/JMDContentCache.mm +42 -0
- package/ios/render/JMDRenderedContent.h +35 -0
- package/ios/render/JMDRenderedContent.mm +274 -0
- package/ios/style/JMDFontScale.h +33 -0
- package/ios/style/JMDLayoutStyle.h +37 -0
- package/ios/style/JMDLayoutStyle.mm +68 -0
- package/ios/style/JMDStyleConfig.h +39 -0
- package/ios/style/JMDStyleConfig.mm +111 -0
- package/ios/style/JMDTextStyle.h +25 -0
- package/ios/style/JMDTextStyle.mm +68 -0
- package/ios/views/JMDBlockStackView.h +18 -0
- package/ios/views/JMDBlockStackView.m +97 -0
- package/ios/views/JMDBlockTextView.h +24 -0
- package/ios/views/JMDBlockTextView.m +340 -0
- package/ios/views/JMDBoxViews.h +33 -0
- package/ios/views/JMDBoxViews.m +292 -0
- package/ios/views/JMDImageView.h +19 -0
- package/ios/views/JMDImageView.m +68 -0
- package/ios/views/JMDMarkdownHost.h +16 -0
- package/ios/views/JMDTableView.h +16 -0
- package/ios/views/JMDTableView.m +172 -0
- package/lib/module/JetMarkdownEditor.js +85 -0
- package/lib/module/JetMarkdownEditor.js.map +1 -0
- package/lib/module/JetMarkdownEditor.native.js +244 -0
- package/lib/module/JetMarkdownEditor.native.js.map +1 -0
- package/lib/module/JetMarkdownEditorNativeComponent.ts +173 -0
- package/lib/module/JetMarkdownView.js +19 -0
- package/lib/module/JetMarkdownView.js.map +1 -0
- package/lib/module/JetMarkdownView.native.js +44 -0
- package/lib/module/JetMarkdownView.native.js.map +1 -0
- package/lib/module/JetMarkdownViewNativeComponent.ts +35 -0
- package/lib/module/defaultStyles.js +122 -0
- package/lib/module/defaultStyles.js.map +1 -0
- package/lib/module/index.js +9 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/serializeStyles.js +259 -0
- package/lib/module/serializeStyles.js.map +1 -0
- package/lib/module/types.js +4 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/useJetMarkdownEditor.js +41 -0
- package/lib/module/useJetMarkdownEditor.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/JetMarkdownEditor.d.ts +6 -0
- package/lib/typescript/src/JetMarkdownEditor.d.ts.map +1 -0
- package/lib/typescript/src/JetMarkdownEditor.native.d.ts +6 -0
- package/lib/typescript/src/JetMarkdownEditor.native.d.ts.map +1 -0
- package/lib/typescript/src/JetMarkdownEditorNativeComponent.d.ts +105 -0
- package/lib/typescript/src/JetMarkdownEditorNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/JetMarkdownView.d.ts +3 -0
- package/lib/typescript/src/JetMarkdownView.d.ts.map +1 -0
- package/lib/typescript/src/JetMarkdownView.native.d.ts +3 -0
- package/lib/typescript/src/JetMarkdownView.native.d.ts.map +1 -0
- package/lib/typescript/src/JetMarkdownViewNativeComponent.d.ts +28 -0
- package/lib/typescript/src/JetMarkdownViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/defaultStyles.d.ts +20 -0
- package/lib/typescript/src/defaultStyles.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +7 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/serializeStyles.d.ts +34 -0
- package/lib/typescript/src/serializeStyles.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +352 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/lib/typescript/src/useJetMarkdownEditor.d.ts +36 -0
- package/lib/typescript/src/useJetMarkdownEditor.d.ts.map +1 -0
- package/package.json +150 -0
- package/react-native.config.js +11 -0
- package/src/JetMarkdownEditor.native.tsx +301 -0
- package/src/JetMarkdownEditor.tsx +90 -0
- package/src/JetMarkdownEditorNativeComponent.ts +173 -0
- package/src/JetMarkdownView.native.tsx +67 -0
- package/src/JetMarkdownView.tsx +16 -0
- package/src/JetMarkdownViewNativeComponent.ts +35 -0
- package/src/defaultStyles.ts +102 -0
- package/src/index.tsx +34 -0
- package/src/serializeStyles.ts +369 -0
- package/src/types.ts +438 -0
- package/src/useJetMarkdownEditor.ts +50 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
#import "JMDBoxViews.h"
|
|
2
|
+
|
|
3
|
+
#import "../render/JMDRenderedContent.h"
|
|
4
|
+
#import "JMDBlockStackView.h"
|
|
5
|
+
#import "JMDBlockTextView.h"
|
|
6
|
+
|
|
7
|
+
@implementation JMDNestedScrollView {
|
|
8
|
+
__weak UIControl *_trackingControl;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
- (instancetype)initWithFrame:(CGRect)frame {
|
|
12
|
+
if (self = [super initWithFrame:frame]) {
|
|
13
|
+
self.delegate = self;
|
|
14
|
+
}
|
|
15
|
+
return self;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// As the hit view this scroller consumes the raw touch stream, which starves
|
|
19
|
+
// UIControl-based wrappers: react-native-gesture-handler's button fires
|
|
20
|
+
// presses from UIControl events, and a control refuses to track touches
|
|
21
|
+
// hit-tested to another view. Synthesize the control events instead — press
|
|
22
|
+
// down on touch start, press on a clean touch up, cancel when the pan takes
|
|
23
|
+
// the touches — so a tap on a code block or table still presses the
|
|
24
|
+
// wrapping card while drags scroll without pressing.
|
|
25
|
+
- (nullable UIControl *)jmdAncestorControl {
|
|
26
|
+
UIView *view = self.superview;
|
|
27
|
+
while (view != nil) {
|
|
28
|
+
if ([view isKindOfClass:[UIControl class]]) {
|
|
29
|
+
return (UIControl *)view;
|
|
30
|
+
}
|
|
31
|
+
view = view.superview;
|
|
32
|
+
}
|
|
33
|
+
return nil;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
|
37
|
+
[super touchesBegan:touches withEvent:event];
|
|
38
|
+
_trackingControl = [self jmdAncestorControl];
|
|
39
|
+
[_trackingControl sendActionsForControlEvents:UIControlEventTouchDown];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
|
43
|
+
[super touchesEnded:touches withEvent:event];
|
|
44
|
+
[_trackingControl sendActionsForControlEvents:UIControlEventTouchUpInside];
|
|
45
|
+
_trackingControl = nil;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
|
|
49
|
+
[super touchesCancelled:touches withEvent:event];
|
|
50
|
+
[_trackingControl sendActionsForControlEvents:UIControlEventTouchCancel];
|
|
51
|
+
_trackingControl = nil;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// This scroller is not a React view, so nothing cancels the JS responder
|
|
55
|
+
// (an RN Pressable wrapping the markdown view) when a drag starts here —
|
|
56
|
+
// React only cancels for its own scroll views. Kill the surface touch
|
|
57
|
+
// handler's active touches the way RCTTouchHandler itself cancels: an
|
|
58
|
+
// enabled toggle.
|
|
59
|
+
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
|
|
60
|
+
UIView *view = self.superview;
|
|
61
|
+
while (view != nil) {
|
|
62
|
+
for (UIGestureRecognizer *recognizer in view.gestureRecognizers) {
|
|
63
|
+
if ([NSStringFromClass(recognizer.class) containsString:@"TouchHandler"]) {
|
|
64
|
+
recognizer.enabled = NO;
|
|
65
|
+
recognizer.enabled = YES;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
view = view.superview;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@end
|
|
74
|
+
|
|
75
|
+
// Shared background + border painting on a host view's layer tree.
|
|
76
|
+
static void JMDApplyBox(UIView *view, JMDLayoutStyle *style) {
|
|
77
|
+
view.backgroundColor = style.backgroundColor ?: UIColor.clearColor;
|
|
78
|
+
view.layer.cornerRadius = style.borderRadius;
|
|
79
|
+
view.layer.cornerCurve =
|
|
80
|
+
style.continuousCorners ? kCACornerCurveContinuous : kCACornerCurveCircular;
|
|
81
|
+
view.layer.masksToBounds = style.borderRadius > 0;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@interface JMDBorderView : UIView
|
|
85
|
+
@property (nonatomic, strong, nullable) JMDLayoutStyle *boxStyle;
|
|
86
|
+
@end
|
|
87
|
+
|
|
88
|
+
@implementation JMDBorderView
|
|
89
|
+
|
|
90
|
+
- (instancetype)initWithFrame:(CGRect)frame {
|
|
91
|
+
if (self = [super initWithFrame:frame]) {
|
|
92
|
+
self.backgroundColor = UIColor.clearColor;
|
|
93
|
+
self.userInteractionEnabled = NO;
|
|
94
|
+
self.contentMode = UIViewContentModeRedraw;
|
|
95
|
+
}
|
|
96
|
+
return self;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
- (void)drawRect:(CGRect)rect {
|
|
100
|
+
JMDLayoutStyle *style = self.boxStyle;
|
|
101
|
+
if (style == nil) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
CGContextRef context = UIGraphicsGetCurrentContext();
|
|
105
|
+
const CGSize size = self.bounds.size;
|
|
106
|
+
|
|
107
|
+
if (style.borderLeftWidth > 0 && style.borderLeftColor != nil) {
|
|
108
|
+
CGContextSetFillColorWithColor(context, style.borderLeftColor.CGColor);
|
|
109
|
+
if (style.borderRadius > 0) {
|
|
110
|
+
UIBezierPath *path = [UIBezierPath
|
|
111
|
+
bezierPathWithRoundedRect:CGRectMake(0, 0, style.borderLeftWidth, size.height)
|
|
112
|
+
cornerRadius:style.borderRadius / 2];
|
|
113
|
+
[path fill];
|
|
114
|
+
} else {
|
|
115
|
+
CGContextFillRect(context, CGRectMake(0, 0, style.borderLeftWidth, size.height));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (style.borderRightWidth > 0 && style.borderRightColor != nil) {
|
|
119
|
+
CGContextSetFillColorWithColor(context, style.borderRightColor.CGColor);
|
|
120
|
+
CGContextFillRect(
|
|
121
|
+
context,
|
|
122
|
+
CGRectMake(size.width - style.borderRightWidth, 0, style.borderRightWidth, size.height));
|
|
123
|
+
}
|
|
124
|
+
if (style.borderTopWidth > 0 && style.borderTopColor != nil) {
|
|
125
|
+
CGContextSetFillColorWithColor(context, style.borderTopColor.CGColor);
|
|
126
|
+
CGContextFillRect(context, CGRectMake(0, 0, size.width, style.borderTopWidth));
|
|
127
|
+
}
|
|
128
|
+
if (style.borderBottomWidth > 0 && style.borderBottomColor != nil) {
|
|
129
|
+
CGContextSetFillColorWithColor(context, style.borderBottomColor.CGColor);
|
|
130
|
+
CGContextFillRect(
|
|
131
|
+
context,
|
|
132
|
+
CGRectMake(0, size.height - style.borderBottomWidth, size.width, style.borderBottomWidth));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
@end
|
|
137
|
+
|
|
138
|
+
@implementation JMDQuoteView {
|
|
139
|
+
JMDMeasuredBlock *_measured;
|
|
140
|
+
JMDBlockStackView *_stack;
|
|
141
|
+
JMDBorderView *_borders;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
- (void)bind:(JMDMeasuredBlock *)measured
|
|
145
|
+
gap:(CGFloat)gap
|
|
146
|
+
host:(nullable id<JMDMarkdownHost>)host {
|
|
147
|
+
_measured = measured;
|
|
148
|
+
if (_stack == nil) {
|
|
149
|
+
_stack = [[JMDBlockStackView alloc] initWithFrame:CGRectZero];
|
|
150
|
+
_borders = [[JMDBorderView alloc] initWithFrame:CGRectZero];
|
|
151
|
+
[self addSubview:_stack];
|
|
152
|
+
[self addSubview:_borders];
|
|
153
|
+
}
|
|
154
|
+
JMDApplyBox(self, measured.block.layoutStyle);
|
|
155
|
+
_borders.boxStyle = measured.block.layoutStyle;
|
|
156
|
+
_stack.host = host;
|
|
157
|
+
[_stack setBlocks:measured.children gap:gap];
|
|
158
|
+
[self setNeedsLayout];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
// Never the hit view itself: markdown touches belong to the host component
|
|
163
|
+
// view; only nested scrollers (code blocks, tables) claim touches.
|
|
164
|
+
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
|
|
165
|
+
UIView *hit = [super hitTest:point withEvent:event];
|
|
166
|
+
return hit == self ? nil : hit;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
- (void)layoutSubviews {
|
|
170
|
+
[super layoutSubviews];
|
|
171
|
+
JMDLayoutStyle *style = _measured.block.layoutStyle;
|
|
172
|
+
const CGFloat left = style.borderLeftWidth + style.paddingLeft;
|
|
173
|
+
const CGFloat top = style.borderTopWidth + style.paddingTop;
|
|
174
|
+
_stack.frame = CGRectMake(
|
|
175
|
+
left,
|
|
176
|
+
top,
|
|
177
|
+
self.bounds.size.width - left - style.borderRightWidth - style.paddingRight,
|
|
178
|
+
self.bounds.size.height - top - style.borderBottomWidth - style.paddingBottom);
|
|
179
|
+
_borders.frame = self.bounds;
|
|
180
|
+
[_borders setNeedsDisplay];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
@end
|
|
184
|
+
|
|
185
|
+
@implementation JMDCodeBlockView {
|
|
186
|
+
JMDMeasuredBlock *_measured;
|
|
187
|
+
UIScrollView *_scroller;
|
|
188
|
+
JMDBlockTextView *_text;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
- (void)bind:(JMDMeasuredBlock *)measured {
|
|
192
|
+
_measured = measured;
|
|
193
|
+
if (_scroller == nil) {
|
|
194
|
+
_scroller = [[JMDNestedScrollView alloc] initWithFrame:CGRectZero];
|
|
195
|
+
_scroller.showsHorizontalScrollIndicator = NO;
|
|
196
|
+
_scroller.showsVerticalScrollIndicator = NO;
|
|
197
|
+
_scroller.alwaysBounceHorizontal = YES;
|
|
198
|
+
_scroller.alwaysBounceVertical = NO;
|
|
199
|
+
_scroller.delaysContentTouches = NO;
|
|
200
|
+
_scroller.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
|
201
|
+
_text = [[JMDBlockTextView alloc] initWithFrame:CGRectZero];
|
|
202
|
+
[_scroller addSubview:_text];
|
|
203
|
+
[self addSubview:_scroller];
|
|
204
|
+
}
|
|
205
|
+
JMDApplyBox(self, measured.block.layoutStyle);
|
|
206
|
+
_text.attributedText = measured.block.attributedText;
|
|
207
|
+
[self setNeedsLayout];
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
// Never the hit view itself: markdown touches belong to the host component
|
|
212
|
+
// view; only nested scrollers (code blocks, tables) claim touches.
|
|
213
|
+
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
|
|
214
|
+
UIView *hit = [super hitTest:point withEvent:event];
|
|
215
|
+
return hit == self ? nil : hit;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
- (void)layoutSubviews {
|
|
219
|
+
[super layoutSubviews];
|
|
220
|
+
JMDLayoutStyle *style = _measured.block.layoutStyle;
|
|
221
|
+
const CGFloat innerWidth =
|
|
222
|
+
self.bounds.size.width - style.paddingLeft - style.paddingRight;
|
|
223
|
+
_scroller.frame = CGRectMake(
|
|
224
|
+
style.paddingLeft, style.paddingTop, innerWidth, _measured.textHeight);
|
|
225
|
+
_text.frame = CGRectMake(0, 0, _measured.contentWidth, _measured.textHeight);
|
|
226
|
+
_scroller.contentSize = CGSizeMake(_measured.contentWidth, _measured.textHeight);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
@end
|
|
230
|
+
|
|
231
|
+
@implementation JMDListBlockView {
|
|
232
|
+
JMDMeasuredBlock *_measured;
|
|
233
|
+
CGFloat _gap;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
- (void)bind:(JMDMeasuredBlock *)measured
|
|
237
|
+
gap:(CGFloat)gap
|
|
238
|
+
host:(nullable id<JMDMarkdownHost>)host {
|
|
239
|
+
_measured = measured;
|
|
240
|
+
_gap = gap;
|
|
241
|
+
for (UIView *subview in [self.subviews copy]) {
|
|
242
|
+
[subview removeFromSuperview];
|
|
243
|
+
}
|
|
244
|
+
JMDBlock *block = measured.block;
|
|
245
|
+
for (NSUInteger i = 0; i < block.rows.count; i++) {
|
|
246
|
+
JMDBlockTextView *marker = [[JMDBlockTextView alloc] initWithFrame:CGRectZero];
|
|
247
|
+
marker.attributedText = block.rows[i].marker;
|
|
248
|
+
[self addSubview:marker];
|
|
249
|
+
|
|
250
|
+
JMDBlockStackView *content = [[JMDBlockStackView alloc] initWithFrame:CGRectZero];
|
|
251
|
+
content.host = host;
|
|
252
|
+
[content setBlocks:measured.rowContents[i] gap:gap];
|
|
253
|
+
[self addSubview:content];
|
|
254
|
+
}
|
|
255
|
+
[self setNeedsLayout];
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
// Never the hit view itself: markdown touches belong to the host component
|
|
260
|
+
// view; only nested scrollers (code blocks, tables) claim touches.
|
|
261
|
+
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
|
|
262
|
+
UIView *hit = [super hitTest:point withEvent:event];
|
|
263
|
+
return hit == self ? nil : hit;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
- (void)layoutSubviews {
|
|
267
|
+
[super layoutSubviews];
|
|
268
|
+
JMDBlock *block = _measured.block;
|
|
269
|
+
const CGFloat markerX = block.listMarginLeft + block.markerMarginLeft;
|
|
270
|
+
const CGFloat contentX = markerX + block.markerWidth;
|
|
271
|
+
const CGFloat contentWidth = _measured.contentWidth;
|
|
272
|
+
|
|
273
|
+
CGFloat y = 0;
|
|
274
|
+
for (NSUInteger i = 0; i < block.rows.count; i++) {
|
|
275
|
+
const CGFloat markerHeight = _measured.markerHeights[i].doubleValue;
|
|
276
|
+
const CGFloat contentHeight =
|
|
277
|
+
[JMDRenderedContent stackHeight:_measured.rowContents[i] gap:_gap];
|
|
278
|
+
const CGFloat rowHeight = MAX(markerHeight, contentHeight);
|
|
279
|
+
|
|
280
|
+
UIView *markerView = self.subviews[i * 2];
|
|
281
|
+
UIView *contentView = self.subviews[i * 2 + 1];
|
|
282
|
+
markerView.frame = CGRectMake(markerX, y, block.markerWidth, markerHeight);
|
|
283
|
+
contentView.frame = CGRectMake(contentX, y, contentWidth, contentHeight);
|
|
284
|
+
|
|
285
|
+
y += rowHeight;
|
|
286
|
+
if (i + 1 < block.rows.count) {
|
|
287
|
+
y += _gap / 2;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
@end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#import <UIKit/UIKit.h>
|
|
2
|
+
|
|
3
|
+
#import "../render/JMDBlock.h"
|
|
4
|
+
#import "JMDMarkdownHost.h"
|
|
5
|
+
|
|
6
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
7
|
+
|
|
8
|
+
/// One markdown image: rounded-corner aspect-fit bitmap, background while
|
|
9
|
+
/// loading. Requests are URL-owned; this view only listens.
|
|
10
|
+
@interface JMDImageView : UIView
|
|
11
|
+
|
|
12
|
+
@property (nonatomic, weak, nullable) id<JMDMarkdownHost> host;
|
|
13
|
+
@property (nonatomic, readonly, nullable) NSString *imageUrl;
|
|
14
|
+
|
|
15
|
+
- (void)bind:(JMDBlock *)block;
|
|
16
|
+
|
|
17
|
+
@end
|
|
18
|
+
|
|
19
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#import "JMDImageView.h"
|
|
2
|
+
|
|
3
|
+
#import <SDWebImage/SDWebImage.h>
|
|
4
|
+
|
|
5
|
+
@implementation JMDImageView {
|
|
6
|
+
JMDBlock *_block;
|
|
7
|
+
SDAnimatedImageView *_imageView;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
- (instancetype)initWithFrame:(CGRect)frame {
|
|
11
|
+
if (self = [super initWithFrame:frame]) {
|
|
12
|
+
// Animated formats (GIF/APNG) play with lazy per-frame decoding and a
|
|
13
|
+
// dynamic frame-buffer cap, so long GIFs in image-heavy feeds do not
|
|
14
|
+
// balloon memory.
|
|
15
|
+
_imageView = [[SDAnimatedImageView alloc] initWithFrame:CGRectZero];
|
|
16
|
+
_imageView.contentMode = UIViewContentModeScaleAspectFit;
|
|
17
|
+
_imageView.clearBufferWhenStopped = YES;
|
|
18
|
+
[self addSubview:_imageView];
|
|
19
|
+
}
|
|
20
|
+
return self;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Hit-test transparent: the host component view owns all touch handling.
|
|
24
|
+
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
|
|
25
|
+
return nil;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
- (nullable NSString *)imageUrl {
|
|
29
|
+
return _block.imageUrl;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
- (void)bind:(JMDBlock *)block {
|
|
33
|
+
_block = block;
|
|
34
|
+
self.backgroundColor = block.imageBackground ?: UIColor.clearColor;
|
|
35
|
+
self.layer.cornerRadius = block.imageBorderRadius;
|
|
36
|
+
self.layer.masksToBounds = block.imageBorderRadius > 0;
|
|
37
|
+
|
|
38
|
+
NSString *url = block.imageUrl ?: @"";
|
|
39
|
+
if (url.length == 0) {
|
|
40
|
+
[_imageView sd_cancelCurrentImageLoad];
|
|
41
|
+
_imageView.image = nil;
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
__weak JMDImageView *weakSelf = self;
|
|
46
|
+
// sd_setImage cancels this view's previous request (recycling) and shares
|
|
47
|
+
// in-flight downloads by URL; completion runs synchronously on memory
|
|
48
|
+
// cache hits, so a fresh view still resizes un-presized images.
|
|
49
|
+
[_imageView sd_setImageWithURL:[NSURL URLWithString:url]
|
|
50
|
+
placeholderImage:nil
|
|
51
|
+
options:SDWebImageRetryFailed | SDWebImageScaleDownLargeImages
|
|
52
|
+
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType,
|
|
53
|
+
NSURL *imageURL) {
|
|
54
|
+
JMDImageView *strongSelf = weakSelf;
|
|
55
|
+
if (strongSelf == nil || image == nil ||
|
|
56
|
+
![strongSelf->_block.imageUrl isEqualToString:url]) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
[strongSelf.host imageIntrinsicSize:image.size forUrl:url];
|
|
60
|
+
}];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
- (void)layoutSubviews {
|
|
64
|
+
[super layoutSubviews];
|
|
65
|
+
_imageView.frame = self.bounds;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#import <UIKit/UIKit.h>
|
|
2
|
+
|
|
3
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
4
|
+
|
|
5
|
+
/// Callbacks from block views up to the host component view.
|
|
6
|
+
@protocol JMDMarkdownHost <NSObject>
|
|
7
|
+
- (void)imageIntrinsicSize:(CGSize)size forUrl:(NSString *)url;
|
|
8
|
+
- (BOOL)isSpoilerRevealed:(NSInteger)spoilerId;
|
|
9
|
+
- (void)toggleSpoiler:(NSInteger)spoilerId;
|
|
10
|
+
- (void)linkPressed:(NSString *)url;
|
|
11
|
+
- (void)linkLongPressed:(NSString *)url;
|
|
12
|
+
/// `frame` is the pressed image's frame in screen coordinates (points).
|
|
13
|
+
- (void)imagePressed:(NSString *)url frame:(CGRect)frame;
|
|
14
|
+
@end
|
|
15
|
+
|
|
16
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#import <UIKit/UIKit.h>
|
|
2
|
+
|
|
3
|
+
#import "../render/JMDBlock.h"
|
|
4
|
+
#import "JMDMarkdownHost.h"
|
|
5
|
+
|
|
6
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
7
|
+
|
|
8
|
+
/// Table: paints the table box, hosts a cell grid in a horizontal scroller
|
|
9
|
+
/// so wide tables keep readable column widths.
|
|
10
|
+
@interface JMDTableView : UIView
|
|
11
|
+
|
|
12
|
+
- (void)bind:(JMDMeasuredBlock *)measured host:(nullable id<JMDMarkdownHost>)host;
|
|
13
|
+
|
|
14
|
+
@end
|
|
15
|
+
|
|
16
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
#import "JMDTableView.h"
|
|
2
|
+
|
|
3
|
+
#import "JMDBlockTextView.h"
|
|
4
|
+
#import "JMDBoxViews.h"
|
|
5
|
+
|
|
6
|
+
/// The unclipped grid inside the scroller: row boxes + cell text.
|
|
7
|
+
@interface JMDTableGridView : UIView
|
|
8
|
+
- (void)bind:(JMDMeasuredBlock *)measured host:(nullable id<JMDMarkdownHost>)host;
|
|
9
|
+
@end
|
|
10
|
+
|
|
11
|
+
@implementation JMDTableGridView {
|
|
12
|
+
JMDMeasuredBlock *_measured;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
- (instancetype)initWithFrame:(CGRect)frame {
|
|
16
|
+
if (self = [super initWithFrame:frame]) {
|
|
17
|
+
self.backgroundColor = UIColor.clearColor;
|
|
18
|
+
self.contentMode = UIViewContentModeRedraw;
|
|
19
|
+
}
|
|
20
|
+
return self;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
- (void)bind:(JMDMeasuredBlock *)measured host:(nullable id<JMDMarkdownHost>)host {
|
|
24
|
+
_measured = measured;
|
|
25
|
+
for (UIView *subview in [self.subviews copy]) {
|
|
26
|
+
[subview removeFromSuperview];
|
|
27
|
+
}
|
|
28
|
+
JMDBlock *block = measured.block;
|
|
29
|
+
for (JMDTableRow *row in block.tableRows) {
|
|
30
|
+
for (NSAttributedString *cell in row.cells) {
|
|
31
|
+
JMDBlockTextView *view = [[JMDBlockTextView alloc] initWithFrame:CGRectZero];
|
|
32
|
+
view.host = host;
|
|
33
|
+
view.attributedText = cell;
|
|
34
|
+
[self addSubview:view];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
[self setNeedsDisplay];
|
|
38
|
+
[self setNeedsLayout];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
|
|
42
|
+
// Touches inside the grid belong to the horizontal scroller.
|
|
43
|
+
UIView *hit = [super hitTest:point withEvent:event];
|
|
44
|
+
return hit == self ? nil : hit;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
- (void)drawRect:(CGRect)rect {
|
|
48
|
+
JMDBlock *block = _measured.block;
|
|
49
|
+
CGContextRef context = UIGraphicsGetCurrentContext();
|
|
50
|
+
const CGFloat width = _measured.contentWidth;
|
|
51
|
+
|
|
52
|
+
CGFloat y = 0;
|
|
53
|
+
NSUInteger rowIndex = 0;
|
|
54
|
+
for (NSNumber *rowHeight in _measured.rowHeights) {
|
|
55
|
+
const BOOL isHeader =
|
|
56
|
+
rowIndex < block.tableRows.count && block.tableRows[rowIndex].isHeader;
|
|
57
|
+
JMDLayoutStyle *rowStyle = isHeader ? block.headerRowStyle : block.bodyRowStyle;
|
|
58
|
+
rowIndex++;
|
|
59
|
+
if (rowStyle.backgroundColor != nil) {
|
|
60
|
+
CGContextSetFillColorWithColor(context, rowStyle.backgroundColor.CGColor);
|
|
61
|
+
CGContextFillRect(context, CGRectMake(0, y, width, rowHeight.doubleValue));
|
|
62
|
+
}
|
|
63
|
+
if (rowStyle.borderBottomWidth > 0 && rowStyle.borderBottomColor != nil) {
|
|
64
|
+
CGContextSetFillColorWithColor(context, rowStyle.borderBottomColor.CGColor);
|
|
65
|
+
CGContextFillRect(
|
|
66
|
+
context,
|
|
67
|
+
CGRectMake(
|
|
68
|
+
0,
|
|
69
|
+
y + rowHeight.doubleValue - rowStyle.borderBottomWidth,
|
|
70
|
+
width,
|
|
71
|
+
rowStyle.borderBottomWidth));
|
|
72
|
+
}
|
|
73
|
+
if (rowStyle.borderTopWidth > 0 && rowStyle.borderTopColor != nil) {
|
|
74
|
+
CGContextSetFillColorWithColor(context, rowStyle.borderTopColor.CGColor);
|
|
75
|
+
CGContextFillRect(context, CGRectMake(0, y, width, rowStyle.borderTopWidth));
|
|
76
|
+
}
|
|
77
|
+
y += rowHeight.doubleValue;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
- (void)layoutSubviews {
|
|
82
|
+
[super layoutSubviews];
|
|
83
|
+
JMDBlock *block = _measured.block;
|
|
84
|
+
|
|
85
|
+
NSUInteger index = 0;
|
|
86
|
+
CGFloat y = 0;
|
|
87
|
+
for (NSUInteger rowIndex = 0; rowIndex < block.tableRows.count; rowIndex++) {
|
|
88
|
+
JMDTableRow *row = block.tableRows[rowIndex];
|
|
89
|
+
JMDLayoutStyle *rowStyle = row.isHeader ? block.headerRowStyle : block.bodyRowStyle;
|
|
90
|
+
const UIEdgeInsets pad = row.isHeader ? block.headerCellPadding : block.cellPadding;
|
|
91
|
+
const CGFloat cellPadH = pad.left + pad.right;
|
|
92
|
+
CGFloat x = 0;
|
|
93
|
+
for (NSUInteger column = 0; column < row.cells.count; column++) {
|
|
94
|
+
if (index >= self.subviews.count) {
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
const CGFloat columnWidth = _measured.columnWidths[column].doubleValue;
|
|
98
|
+
const CGFloat cellHeight = _measured.rowHeights[rowIndex].doubleValue -
|
|
99
|
+
pad.top - pad.bottom -
|
|
100
|
+
rowStyle.borderTopWidth - rowStyle.borderBottomWidth;
|
|
101
|
+
self.subviews[index].frame = CGRectMake(
|
|
102
|
+
x + pad.left,
|
|
103
|
+
y + pad.top + rowStyle.borderTopWidth,
|
|
104
|
+
MAX(columnWidth - cellPadH, 1),
|
|
105
|
+
MAX(cellHeight, 0));
|
|
106
|
+
index++;
|
|
107
|
+
x += columnWidth;
|
|
108
|
+
}
|
|
109
|
+
y += _measured.rowHeights[rowIndex].doubleValue;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@end
|
|
114
|
+
|
|
115
|
+
@implementation JMDTableView {
|
|
116
|
+
JMDMeasuredBlock *_measured;
|
|
117
|
+
UIScrollView *_scroller;
|
|
118
|
+
JMDTableGridView *_grid;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
- (void)bind:(JMDMeasuredBlock *)measured host:(nullable id<JMDMarkdownHost>)host {
|
|
122
|
+
_measured = measured;
|
|
123
|
+
if (_scroller == nil) {
|
|
124
|
+
_scroller = [[JMDNestedScrollView alloc] initWithFrame:CGRectZero];
|
|
125
|
+
_scroller.showsHorizontalScrollIndicator = NO;
|
|
126
|
+
_scroller.showsVerticalScrollIndicator = NO;
|
|
127
|
+
_scroller.alwaysBounceVertical = NO;
|
|
128
|
+
_scroller.delaysContentTouches = NO;
|
|
129
|
+
_scroller.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
|
130
|
+
_grid = [[JMDTableGridView alloc] initWithFrame:CGRectZero];
|
|
131
|
+
[_scroller addSubview:_grid];
|
|
132
|
+
[self addSubview:_scroller];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
JMDLayoutStyle *style = measured.block.layoutStyle;
|
|
136
|
+
self.backgroundColor = style.backgroundColor ?: UIColor.clearColor;
|
|
137
|
+
self.layer.cornerRadius = style.borderRadius;
|
|
138
|
+
self.layer.cornerCurve =
|
|
139
|
+
style.continuousCorners ? kCACornerCurveContinuous : kCACornerCurveCircular;
|
|
140
|
+
self.layer.masksToBounds = style.borderRadius > 0;
|
|
141
|
+
|
|
142
|
+
[_grid bind:measured host:host];
|
|
143
|
+
[self setNeedsLayout];
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
// Never the hit view itself: markdown touches belong to the host component
|
|
148
|
+
// view; only nested scrollers (code blocks, tables) claim touches.
|
|
149
|
+
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
|
|
150
|
+
UIView *hit = [super hitTest:point withEvent:event];
|
|
151
|
+
return hit == self ? nil : hit;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
- (void)layoutSubviews {
|
|
155
|
+
[super layoutSubviews];
|
|
156
|
+
JMDLayoutStyle *style = _measured.block.layoutStyle;
|
|
157
|
+
CGFloat gridHeight = 0;
|
|
158
|
+
for (NSNumber *rowHeight in _measured.rowHeights) {
|
|
159
|
+
gridHeight += rowHeight.doubleValue;
|
|
160
|
+
}
|
|
161
|
+
const CGFloat left = style.borderLeftWidth + style.paddingLeft;
|
|
162
|
+
const CGFloat top = style.borderTopWidth + style.paddingTop;
|
|
163
|
+
_scroller.frame = CGRectMake(
|
|
164
|
+
left,
|
|
165
|
+
top,
|
|
166
|
+
self.bounds.size.width - left - style.borderRightWidth - style.paddingRight,
|
|
167
|
+
gridHeight);
|
|
168
|
+
_grid.frame = CGRectMake(0, 0, _measured.contentWidth, gridHeight);
|
|
169
|
+
_scroller.contentSize = CGSizeMake(_measured.contentWidth, gridHeight);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
@end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useImperativeHandle, useRef } from "react";
|
|
4
|
+
import { TextInput } from "react-native";
|
|
5
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
|
+
// Non-native (web) fallback: a plain multiline text input over raw markdown.
|
|
7
|
+
export function JetMarkdownEditor({
|
|
8
|
+
allowFontScaling,
|
|
9
|
+
autoCapitalize,
|
|
10
|
+
autoCorrect,
|
|
11
|
+
autoFocus,
|
|
12
|
+
cursorColor,
|
|
13
|
+
defaultValue,
|
|
14
|
+
editable,
|
|
15
|
+
multiline = true,
|
|
16
|
+
onBlur,
|
|
17
|
+
onChangeMarkdown,
|
|
18
|
+
onChangeText,
|
|
19
|
+
onFocus,
|
|
20
|
+
placeholder,
|
|
21
|
+
placeholderTextColor,
|
|
22
|
+
scrollEnabled,
|
|
23
|
+
selectionColor,
|
|
24
|
+
style,
|
|
25
|
+
ref
|
|
26
|
+
}) {
|
|
27
|
+
const inputRef = useRef(null);
|
|
28
|
+
const textRef = useRef(defaultValue ?? "");
|
|
29
|
+
useImperativeHandle(ref, () => ({
|
|
30
|
+
blur: () => inputRef.current?.blur(),
|
|
31
|
+
focus: () => inputRef.current?.focus(),
|
|
32
|
+
getMarkdown: () => Promise.resolve(textRef.current),
|
|
33
|
+
insertLink: () => undefined,
|
|
34
|
+
insertMarkdown: () => undefined,
|
|
35
|
+
insertMention: () => undefined,
|
|
36
|
+
removeLink: () => undefined,
|
|
37
|
+
setSelection: () => {
|
|
38
|
+
// Not supported in the web fallback.
|
|
39
|
+
},
|
|
40
|
+
setValue: markdown => {
|
|
41
|
+
textRef.current = markdown;
|
|
42
|
+
inputRef.current?.setNativeProps({
|
|
43
|
+
text: markdown
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
// Formatting toggles are not supported in the web fallback (raw
|
|
47
|
+
// markdown).
|
|
48
|
+
toggleBlockQuote: () => undefined,
|
|
49
|
+
toggleBold: () => undefined,
|
|
50
|
+
toggleCode: () => undefined,
|
|
51
|
+
toggleCodeBlock: () => undefined,
|
|
52
|
+
toggleHeading: () => undefined,
|
|
53
|
+
toggleItalic: () => undefined,
|
|
54
|
+
toggleOrderedList: () => undefined,
|
|
55
|
+
toggleSpoiler: () => undefined,
|
|
56
|
+
toggleStrikethrough: () => undefined,
|
|
57
|
+
toggleSubscript: () => undefined,
|
|
58
|
+
toggleSuperscript: () => undefined,
|
|
59
|
+
toggleUnorderedList: () => undefined
|
|
60
|
+
}), []);
|
|
61
|
+
return /*#__PURE__*/_jsx(TextInput, {
|
|
62
|
+
allowFontScaling: allowFontScaling,
|
|
63
|
+
autoCapitalize: autoCapitalize,
|
|
64
|
+
autoCorrect: autoCorrect,
|
|
65
|
+
autoFocus: autoFocus,
|
|
66
|
+
cursorColor: cursorColor,
|
|
67
|
+
defaultValue: defaultValue,
|
|
68
|
+
editable: editable,
|
|
69
|
+
multiline: multiline,
|
|
70
|
+
onBlur: onBlur,
|
|
71
|
+
onChangeText: text => {
|
|
72
|
+
textRef.current = text;
|
|
73
|
+
onChangeText?.(text);
|
|
74
|
+
onChangeMarkdown?.(text);
|
|
75
|
+
},
|
|
76
|
+
onFocus: onFocus,
|
|
77
|
+
placeholder: placeholder,
|
|
78
|
+
placeholderTextColor: placeholderTextColor,
|
|
79
|
+
ref: inputRef,
|
|
80
|
+
scrollEnabled: scrollEnabled,
|
|
81
|
+
selectionColor: selectionColor,
|
|
82
|
+
style: style
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=JetMarkdownEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useImperativeHandle","useRef","TextInput","jsx","_jsx","JetMarkdownEditor","allowFontScaling","autoCapitalize","autoCorrect","autoFocus","cursorColor","defaultValue","editable","multiline","onBlur","onChangeMarkdown","onChangeText","onFocus","placeholder","placeholderTextColor","scrollEnabled","selectionColor","style","ref","inputRef","textRef","blur","current","focus","getMarkdown","Promise","resolve","insertLink","undefined","insertMarkdown","insertMention","removeLink","setSelection","setValue","markdown","setNativeProps","text","toggleBlockQuote","toggleBold","toggleCode","toggleCodeBlock","toggleHeading","toggleItalic","toggleOrderedList","toggleSpoiler","toggleStrikethrough","toggleSubscript","toggleSuperscript","toggleUnorderedList"],"sourceRoot":"../../src","sources":["JetMarkdownEditor.tsx"],"mappings":"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","ignoreList":[]}
|