@expensify/react-native-live-markdown 0.1.187 → 0.1.189
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 +55 -8
- package/RNLiveMarkdown.podspec +2 -4
- package/android/build.gradle +4 -9
- package/android/src/main/cpp/CMakeLists.txt +14 -6
- package/android/src/main/cpp/MarkdownUtils.cpp +13 -24
- package/android/src/main/cpp/MarkdownUtils.h +2 -7
- package/android/src/main/cpp/OnLoad.cpp +6 -0
- package/android/src/main/java/com/expensify/livemarkdown/CustomFabricUIManager.java +2 -2
- package/android/src/main/java/com/expensify/livemarkdown/CustomMountingManager.java +4 -6
- package/android/src/main/java/com/expensify/livemarkdown/LiveMarkdownModule.java +12 -0
- package/android/src/main/java/com/expensify/livemarkdown/MarkdownTextInputDecoratorView.java +17 -3
- package/android/src/main/java/com/expensify/livemarkdown/MarkdownTextInputDecoratorViewManager.java +6 -0
- package/android/src/main/java/com/expensify/livemarkdown/MarkdownUtils.java +21 -34
- package/android/src/main/new_arch/MarkdownCommitHook.cpp +7 -4
- package/android/src/main/new_arch/MarkdownCommitHook.h +2 -0
- package/android/src/newarch/LiveMarkdownModuleSpec.java +9 -0
- package/android/src/oldarch/LiveMarkdownModuleSpec.java +12 -0
- package/android/src/oldarch/MarkdownTextInputDecoratorViewManagerSpec.java +1 -0
- package/apple/LiveMarkdownModule.h +16 -0
- package/apple/{RCTLiveMarkdownModule.mm → LiveMarkdownModule.mm} +31 -17
- package/apple/MarkdownCommitHook.mm +2 -0
- package/apple/MarkdownTextInputDecoratorComponentView.mm +4 -0
- package/apple/MarkdownTextInputDecoratorView.h +2 -0
- package/apple/MarkdownTextInputDecoratorView.mm +13 -0
- package/apple/MarkdownTextInputDecoratorViewManager.mm +9 -0
- package/apple/RCTMarkdownUtils.h +1 -0
- package/apple/RCTMarkdownUtils.mm +43 -45
- package/cpp/MarkdownGlobal.cpp +45 -0
- package/cpp/MarkdownGlobal.h +24 -0
- package/cpp/RuntimeDecorator.cpp +43 -0
- package/cpp/RuntimeDecorator.h +13 -0
- package/lib/commonjs/MarkdownTextInput.js +43 -2
- package/lib/commonjs/MarkdownTextInput.js.map +1 -1
- package/lib/commonjs/MarkdownTextInput.web.js +20 -14
- package/lib/commonjs/MarkdownTextInput.web.js.map +1 -1
- package/lib/commonjs/MarkdownTextInputDecoratorViewNativeComponent.js.map +1 -1
- package/lib/commonjs/index.js +7 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/parseExpensiMark.js +263 -0
- package/lib/commonjs/parseExpensiMark.js.map +1 -0
- package/lib/commonjs/web/utils/parserUtils.js +2 -2
- package/lib/commonjs/web/utils/parserUtils.js.map +1 -1
- package/lib/module/MarkdownTextInput.js +43 -2
- package/lib/module/MarkdownTextInput.js.map +1 -1
- package/lib/module/MarkdownTextInput.web.js +20 -14
- package/lib/module/MarkdownTextInput.web.js.map +1 -1
- package/lib/module/MarkdownTextInputDecoratorViewNativeComponent.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/parseExpensiMark.js +258 -0
- package/lib/module/parseExpensiMark.js.map +1 -0
- package/lib/module/web/utils/parserUtils.js +2 -2
- package/lib/module/web/utils/parserUtils.js.map +1 -1
- package/lib/typescript/src/MarkdownTextInput.d.ts +9 -1
- package/lib/typescript/src/MarkdownTextInput.d.ts.map +1 -1
- package/lib/typescript/src/MarkdownTextInput.web.d.ts +2 -1
- package/lib/typescript/src/MarkdownTextInput.web.d.ts.map +1 -1
- package/lib/typescript/src/MarkdownTextInputDecoratorViewNativeComponent.d.ts +2 -1
- package/lib/typescript/src/MarkdownTextInputDecoratorViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/parseExpensiMark.d.ts +4 -0
- package/lib/typescript/src/parseExpensiMark.d.ts.map +1 -0
- package/lib/typescript/src/web/utils/parserUtils.d.ts +1 -1
- package/lib/typescript/src/web/utils/parserUtils.d.ts.map +1 -1
- package/package.json +13 -10
- package/src/MarkdownTextInput.tsx +62 -2
- package/src/MarkdownTextInput.web.tsx +23 -15
- package/src/MarkdownTextInputDecoratorViewNativeComponent.ts +2 -1
- package/src/index.tsx +2 -0
- package/src/parseExpensiMark.ts +277 -0
- package/src/web/utils/parserUtils.ts +2 -1
- package/apple/RCTLiveMarkdownModule.h +0 -16
- package/lib/parser/react-native-live-markdown-parser.js +0 -29
- package/parser/react-native-live-markdown-parser.js +0 -29
|
@@ -1,40 +1,55 @@
|
|
|
1
|
+
#import "LiveMarkdownModule.h"
|
|
2
|
+
|
|
3
|
+
#import <RNLiveMarkdown/RuntimeDecorator.h>
|
|
4
|
+
|
|
1
5
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
6
|
+
#import <RNLiveMarkdown/MarkdownCommitHook.h>
|
|
7
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
2
8
|
|
|
9
|
+
#import <React/RCTBridge+Private.h>
|
|
10
|
+
|
|
11
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
3
12
|
#import <React/RCTScheduler.h>
|
|
4
13
|
#import <React/RCTSurfacePresenter.h>
|
|
14
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
5
15
|
|
|
6
|
-
#import
|
|
7
|
-
#import "MarkdownShadowFamilyRegistry.h"
|
|
8
|
-
#import "RCTLiveMarkdownModule.h"
|
|
16
|
+
#import <jsi/jsi.h>
|
|
9
17
|
|
|
18
|
+
using namespace facebook;
|
|
10
19
|
using namespace expensify::livemarkdown;
|
|
11
20
|
|
|
12
21
|
// A turbomodule used to register the commit hook
|
|
13
22
|
// I think this is the easiest way to access the UIManager, which we need to
|
|
14
23
|
// actually register the hook
|
|
15
24
|
|
|
16
|
-
@implementation
|
|
17
|
-
|
|
25
|
+
@implementation LiveMarkdownModule {
|
|
26
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
18
27
|
std::shared_ptr<MarkdownCommitHook> commitHook_;
|
|
19
28
|
__weak RCTSurfacePresenter *surfacePresenter_;
|
|
29
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
20
30
|
}
|
|
21
31
|
|
|
22
|
-
RCT_EXPORT_MODULE(
|
|
32
|
+
RCT_EXPORT_MODULE()
|
|
23
33
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
34
|
+
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install)
|
|
35
|
+
{
|
|
36
|
+
RCTCxxBridge *cxxBridge = (RCTCxxBridge *)self.bridge;
|
|
37
|
+
jsi::Runtime &rt = *(jsi::Runtime *)cxxBridge.runtime;
|
|
38
|
+
expensify::livemarkdown::injectJSIBindings(rt);
|
|
27
39
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
40
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
41
|
+
RCTScheduler *scheduler = [surfacePresenter_ scheduler];
|
|
42
|
+
commitHook_ = std::make_shared<MarkdownCommitHook>(scheduler.uiManager);
|
|
43
|
+
#endif // RCT_NEW_ARCH_ENABLED
|
|
44
|
+
|
|
45
|
+
return @(1);
|
|
32
46
|
}
|
|
33
47
|
|
|
48
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
49
|
+
|
|
34
50
|
- (void)handleJavaScriptDidLoadNotification:(NSNotification *)notification
|
|
35
51
|
{
|
|
36
52
|
surfacePresenter_ = self.bridge.surfacePresenter;
|
|
37
|
-
[self install];
|
|
38
53
|
}
|
|
39
54
|
|
|
40
55
|
- (void)setBridge:(RCTBridge *)bridge
|
|
@@ -62,7 +77,6 @@ RCT_EXPORT_MODULE(@"LiveMarkdownModule")
|
|
|
62
77
|
surfacePresenter_ = surfacePresenter;
|
|
63
78
|
}
|
|
64
79
|
|
|
65
|
-
|
|
66
80
|
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
67
81
|
(const facebook::react::ObjCTurboModule::InitParams &)params {
|
|
68
82
|
return std::make_shared<facebook::react::NativeLiveMarkdownModuleSpecJSI>(
|
|
@@ -75,6 +89,6 @@ RCT_EXPORT_MODULE(@"LiveMarkdownModule")
|
|
|
75
89
|
[super invalidate];
|
|
76
90
|
}
|
|
77
91
|
|
|
78
|
-
@end
|
|
79
|
-
|
|
80
92
|
#endif // RCT_NEW_ARCH_ENABLED
|
|
93
|
+
|
|
94
|
+
@end
|
|
@@ -158,6 +158,7 @@ RootShadowNode::Unshared MarkdownCommitHook::shadowTreeWillCommit(
|
|
|
158
158
|
usedUtils =
|
|
159
159
|
MarkdownCommitHook::getOrCreateMarkdownUtils(*nodes.decorator);
|
|
160
160
|
[usedUtils setMarkdownStyle:markdownStyle];
|
|
161
|
+
[usedUtils setParserId:@(markdownProps.parserId)];
|
|
161
162
|
|
|
162
163
|
// convert the attibuted string stored in state to
|
|
163
164
|
// NSAttributedString
|
|
@@ -236,6 +237,7 @@ RootShadowNode::Unshared MarkdownCommitHook::shadowTreeWillCommit(
|
|
|
236
237
|
usedUtils =
|
|
237
238
|
MarkdownCommitHook::getOrCreateMarkdownUtils(*nodes.decorator);
|
|
238
239
|
[usedUtils setMarkdownStyle:markdownStyle];
|
|
240
|
+
[usedUtils setParserId:@(markdownProps.parserId)];
|
|
239
241
|
|
|
240
242
|
// convert the attibuted string stored in state to
|
|
241
243
|
// NSAttributedString
|
|
@@ -68,6 +68,10 @@ using namespace facebook::react;
|
|
|
68
68
|
const auto &oldViewProps = *std::static_pointer_cast<MarkdownTextInputDecoratorViewProps const>(_props);
|
|
69
69
|
const auto &newViewProps = *std::static_pointer_cast<MarkdownTextInputDecoratorViewProps const>(props);
|
|
70
70
|
|
|
71
|
+
if (oldViewProps.parserId != newViewProps.parserId) {
|
|
72
|
+
[_view setParserId:@(newViewProps.parserId)];
|
|
73
|
+
}
|
|
74
|
+
|
|
71
75
|
// TODO: if (oldViewProps.markdownStyle != newViewProps.markdownStyle)
|
|
72
76
|
RCTMarkdownStyle *markdownStyle = [[RCTMarkdownStyle alloc] initWithStruct:newViewProps.markdownStyle];
|
|
73
77
|
[_view setMarkdownStyle:markdownStyle];
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
@implementation MarkdownTextInputDecoratorView {
|
|
18
18
|
RCTMarkdownUtils *_markdownUtils;
|
|
19
19
|
RCTMarkdownStyle *_markdownStyle;
|
|
20
|
+
NSNumber *_parserId;
|
|
20
21
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
21
22
|
__weak RCTTextInputComponentView *_textInput;
|
|
22
23
|
#else
|
|
@@ -62,6 +63,7 @@
|
|
|
62
63
|
_markdownUtils = [[RCTMarkdownUtils alloc] init];
|
|
63
64
|
react_native_assert(_markdownStyle != nil);
|
|
64
65
|
[_markdownUtils setMarkdownStyle:_markdownStyle];
|
|
66
|
+
[_markdownUtils setParserId:_parserId];
|
|
65
67
|
|
|
66
68
|
[_textInput setMarkdownUtils:_markdownUtils];
|
|
67
69
|
if ([_backedTextInputView isKindOfClass:[RCTUITextField class]]) {
|
|
@@ -109,7 +111,18 @@
|
|
|
109
111
|
{
|
|
110
112
|
_markdownStyle = markdownStyle;
|
|
111
113
|
[_markdownUtils setMarkdownStyle:markdownStyle];
|
|
114
|
+
[self applyNewStyles];
|
|
115
|
+
}
|
|
112
116
|
|
|
117
|
+
- (void)setParserId:(NSNumber *)parserId
|
|
118
|
+
{
|
|
119
|
+
_parserId = parserId;
|
|
120
|
+
[_markdownUtils setParserId:parserId];
|
|
121
|
+
[self applyNewStyles];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
- (void)applyNewStyles
|
|
125
|
+
{
|
|
113
126
|
if (_textView != nil) {
|
|
114
127
|
// We want to use `textStorage` for applying markdown when possible. Currently it's only available for UITextView
|
|
115
128
|
[_textView textDidChange];
|
|
@@ -20,4 +20,13 @@ RCT_CUSTOM_VIEW_PROPERTY(markdownStyle, NSDictionary, MarkdownTextInputDecorator
|
|
|
20
20
|
#endif /* RCT_NEW_ARCH_ENABLED */
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
RCT_CUSTOM_VIEW_PROPERTY(parserId, NSNumber, MarkdownTextInputDecoratorView)
|
|
24
|
+
{
|
|
25
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
26
|
+
// implemented in MarkdownTextInputDecoratorView updateProps:
|
|
27
|
+
#else
|
|
28
|
+
[view setParserId:json];
|
|
29
|
+
#endif /* RCT_NEW_ARCH_ENABLED */
|
|
30
|
+
}
|
|
31
|
+
|
|
23
32
|
@end
|
package/apple/RCTMarkdownUtils.h
CHANGED
|
@@ -6,6 +6,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
6
6
|
@interface RCTMarkdownUtils : NSObject
|
|
7
7
|
|
|
8
8
|
@property (nonatomic) RCTMarkdownStyle *markdownStyle;
|
|
9
|
+
@property (nonatomic) NSNumber *parserId;
|
|
9
10
|
@property (nonatomic) NSMutableArray<NSDictionary *> *blockquoteRangesAndLevels;
|
|
10
11
|
|
|
11
12
|
- (NSAttributedString *)parseMarkdown:(nullable NSAttributedString *)input withAttributes:(nullable NSDictionary<NSAttributedStringKey, id>*)attributes;
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
#import <RNLiveMarkdown/RCTMarkdownUtils.h>
|
|
2
|
+
#import <RNLiveMarkdown/MarkdownGlobal.h>
|
|
2
3
|
#import "react_native_assert.h"
|
|
3
4
|
#import <React/RCTAssert.h>
|
|
4
5
|
#import <React/RCTFont.h>
|
|
5
|
-
|
|
6
6
|
#include <jsi/jsi.h>
|
|
7
|
-
#include <hermes/hermes.h>
|
|
8
|
-
|
|
9
|
-
using namespace facebook;
|
|
10
7
|
|
|
11
8
|
@implementation RCTMarkdownUtils {
|
|
12
9
|
NSString *_prevInputString;
|
|
13
10
|
NSAttributedString *_prevAttributedString;
|
|
14
11
|
NSDictionary<NSAttributedStringKey, id> *_prevTextAttributes;
|
|
15
12
|
__weak RCTMarkdownStyle *_prevMarkdownStyle;
|
|
13
|
+
__weak NSNumber *_prevParserId;
|
|
16
14
|
}
|
|
17
15
|
|
|
18
16
|
- (NSAttributedString *)parseMarkdown:(nullable NSAttributedString *)input withAttributes:(nullable NSDictionary<NSAttributedStringKey,id> *)attributes
|
|
@@ -23,64 +21,64 @@ using namespace facebook;
|
|
|
23
21
|
}
|
|
24
22
|
|
|
25
23
|
NSString *inputString = [input string];
|
|
26
|
-
if ([inputString isEqualToString:_prevInputString] && [attributes isEqualToDictionary:_prevTextAttributes] && [_markdownStyle isEqual:_prevMarkdownStyle]) {
|
|
24
|
+
if ([inputString isEqualToString:_prevInputString] && [attributes isEqualToDictionary:_prevTextAttributes] && [_markdownStyle isEqual:_prevMarkdownStyle] && [_parserId isEqualToNumber:_prevParserId]) {
|
|
27
25
|
return _prevAttributedString;
|
|
28
26
|
}
|
|
29
27
|
|
|
30
|
-
static std::shared_ptr<jsi::Runtime> runtime;
|
|
31
28
|
static std::mutex runtimeMutex;
|
|
32
29
|
auto lock = std::lock_guard<std::mutex>(runtimeMutex);
|
|
33
30
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
assert(path != nil && "[react-native-live-markdown] Markdown parser bundle not found");
|
|
37
|
-
NSString *content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL];
|
|
38
|
-
assert(content != nil && "[react-native-live-markdown] Markdown parser bundle is empty");
|
|
39
|
-
runtime = facebook::hermes::makeHermesRuntime();
|
|
40
|
-
auto codeBuffer = std::make_shared<const jsi::StringBuffer>([content UTF8String]);
|
|
41
|
-
runtime->evaluateJavaScript(codeBuffer, "evaluateJavaScript");
|
|
42
|
-
}
|
|
31
|
+
auto markdownRuntime = expensify::livemarkdown::getMarkdownRuntime();
|
|
32
|
+
jsi::Runtime &rt = markdownRuntime->getJSIRuntime();
|
|
43
33
|
|
|
44
|
-
|
|
45
|
-
auto text = jsi::String::createFromUtf8(rt, [inputString UTF8String]);
|
|
34
|
+
auto markdownWorklet = expensify::livemarkdown::getMarkdownWorklet([_parserId intValue]);
|
|
46
35
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
const auto &ranges = output.asObject(rt).asArray(rt);
|
|
36
|
+
try {
|
|
37
|
+
const auto &text = jsi::String::createFromUtf8(rt, [inputString UTF8String]);
|
|
38
|
+
const auto &output = markdownRuntime->runGuarded(markdownWorklet, text);
|
|
39
|
+
const auto &ranges = output.asObject(rt).asArray(rt);
|
|
53
40
|
|
|
54
|
-
|
|
55
|
-
|
|
41
|
+
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:inputString attributes:attributes];
|
|
42
|
+
[attributedString beginEditing];
|
|
56
43
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
44
|
+
// If the attributed string ends with underlined text, blurring the single-line input imprints the underline style across the whole string.
|
|
45
|
+
// It looks like a bug in iOS, as there is no underline style to be found in the attributed string, especially after formatting.
|
|
46
|
+
// This is a workaround that applies the NSUnderlineStyleNone to the string before iterating over ranges which resolves this problem.
|
|
47
|
+
[attributedString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleNone] range:NSMakeRange(0, attributedString.length)];
|
|
61
48
|
|
|
62
|
-
|
|
49
|
+
_blockquoteRangesAndLevels = [NSMutableArray new];
|
|
63
50
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
51
|
+
for (size_t i = 0, n = ranges.size(rt); i < n; ++i) {
|
|
52
|
+
const auto &item = ranges.getValueAtIndex(rt, i).asObject(rt);
|
|
53
|
+
const auto &type = item.getProperty(rt, "type").asString(rt).utf8(rt);
|
|
54
|
+
const auto &start = static_cast<int>(item.getProperty(rt, "start").asNumber());
|
|
55
|
+
const auto &length = static_cast<int>(item.getProperty(rt, "length").asNumber());
|
|
56
|
+
const auto &depth = item.hasProperty(rt, "depth") ? static_cast<int>(item.getProperty(rt, "depth").asNumber()) : 1;
|
|
70
57
|
|
|
71
|
-
|
|
72
|
-
|
|
58
|
+
[self applyRangeToAttributedString:attributedString type:type start:start length:length depth:depth];
|
|
59
|
+
}
|
|
73
60
|
|
|
74
|
-
|
|
61
|
+
RCTApplyBaselineOffset(attributedString);
|
|
75
62
|
|
|
76
|
-
|
|
63
|
+
[attributedString endEditing];
|
|
77
64
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
65
|
+
_prevInputString = inputString;
|
|
66
|
+
_prevAttributedString = attributedString;
|
|
67
|
+
_prevTextAttributes = attributes;
|
|
68
|
+
_prevMarkdownStyle = _markdownStyle;
|
|
69
|
+
_prevParserId = _parserId;
|
|
82
70
|
|
|
83
|
-
|
|
71
|
+
return attributedString;
|
|
72
|
+
} catch (const jsi::JSError &error) {
|
|
73
|
+
RCTLogWarn(@"[react-native-live-markdown] Incorrect schema of worklet parser output: %s", error.getMessage().c_str());
|
|
74
|
+
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:inputString attributes:attributes];
|
|
75
|
+
_prevInputString = inputString;
|
|
76
|
+
_prevAttributedString = attributedString;
|
|
77
|
+
_prevTextAttributes = attributes;
|
|
78
|
+
_prevMarkdownStyle = _markdownStyle;
|
|
79
|
+
_prevParserId = _parserId;
|
|
80
|
+
return attributedString;
|
|
81
|
+
}
|
|
84
82
|
}
|
|
85
83
|
}
|
|
86
84
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#include "MarkdownGlobal.h"
|
|
2
|
+
|
|
3
|
+
#include <unordered_map>
|
|
4
|
+
|
|
5
|
+
using namespace facebook;
|
|
6
|
+
|
|
7
|
+
namespace expensify {
|
|
8
|
+
namespace livemarkdown {
|
|
9
|
+
|
|
10
|
+
std::shared_ptr<WorkletRuntime> globalMarkdownWorkletRuntime;
|
|
11
|
+
|
|
12
|
+
void setMarkdownRuntime(const std::shared_ptr<WorkletRuntime> &markdownWorkletRuntime) {
|
|
13
|
+
globalMarkdownWorkletRuntime = markdownWorkletRuntime;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
std::shared_ptr<WorkletRuntime> getMarkdownRuntime() {
|
|
17
|
+
return globalMarkdownWorkletRuntime;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
std::unordered_map<int, std::shared_ptr<ShareableWorklet>> globalMarkdownShareableWorklets;
|
|
21
|
+
std::mutex globalMarkdownShareableWorkletsMutex;
|
|
22
|
+
int nextParserId = 1;
|
|
23
|
+
|
|
24
|
+
const int registerMarkdownWorklet(const std::shared_ptr<ShareableWorklet> &markdownWorklet) {
|
|
25
|
+
assert(markdownWorklet != nullptr);
|
|
26
|
+
auto parserId = nextParserId++;
|
|
27
|
+
std::unique_lock<std::mutex> lock(globalMarkdownShareableWorkletsMutex);
|
|
28
|
+
globalMarkdownShareableWorklets[parserId] = markdownWorklet;
|
|
29
|
+
return parserId;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
void unregisterMarkdownWorklet(const int parserId) {
|
|
33
|
+
std::unique_lock<std::mutex> lock(globalMarkdownShareableWorkletsMutex);
|
|
34
|
+
globalMarkdownShareableWorklets.erase(parserId);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
std::shared_ptr<ShareableWorklet> getMarkdownWorklet(const int parserId) {
|
|
38
|
+
std::unique_lock<std::mutex> lock(globalMarkdownShareableWorkletsMutex);
|
|
39
|
+
const auto &worklet = globalMarkdownShareableWorklets[parserId];
|
|
40
|
+
assert(worklet != nullptr);
|
|
41
|
+
return worklet;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
} // namespace livemarkdown
|
|
45
|
+
} // namespace expensify
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <jsi/jsi.h>
|
|
4
|
+
|
|
5
|
+
#include <worklets/WorkletRuntime/WorkletRuntime.h>
|
|
6
|
+
|
|
7
|
+
using namespace facebook;
|
|
8
|
+
using namespace worklets;
|
|
9
|
+
|
|
10
|
+
namespace expensify {
|
|
11
|
+
namespace livemarkdown {
|
|
12
|
+
|
|
13
|
+
void setMarkdownRuntime(const std::shared_ptr<WorkletRuntime> &markdownWorkletRuntime);
|
|
14
|
+
|
|
15
|
+
std::shared_ptr<WorkletRuntime> getMarkdownRuntime();
|
|
16
|
+
|
|
17
|
+
const int registerMarkdownWorklet(const std::shared_ptr<ShareableWorklet> &markdownWorklet);
|
|
18
|
+
|
|
19
|
+
void unregisterMarkdownWorklet(const int parserId);
|
|
20
|
+
|
|
21
|
+
std::shared_ptr<ShareableWorklet> getMarkdownWorklet(const int parserId);
|
|
22
|
+
|
|
23
|
+
} // namespace livemarkdown
|
|
24
|
+
} // namespace expensify
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#include "RuntimeDecorator.h"
|
|
2
|
+
#include "MarkdownGlobal.h"
|
|
3
|
+
|
|
4
|
+
using namespace facebook;
|
|
5
|
+
using namespace worklets;
|
|
6
|
+
|
|
7
|
+
namespace expensify {
|
|
8
|
+
namespace livemarkdown {
|
|
9
|
+
|
|
10
|
+
void injectJSIBindings(jsi::Runtime &rt) {
|
|
11
|
+
|
|
12
|
+
rt.global().setProperty(rt, "jsi_setMarkdownRuntime", jsi::Function::createFromHostFunction(
|
|
13
|
+
rt,
|
|
14
|
+
jsi::PropNameID::forAscii(rt, "jsi_setMarkdownRuntime"),
|
|
15
|
+
1,
|
|
16
|
+
[](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value {
|
|
17
|
+
setMarkdownRuntime(extractWorkletRuntime(rt, args[0]));
|
|
18
|
+
return jsi::Value::undefined();
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
rt.global().setProperty(rt, "jsi_registerMarkdownWorklet", jsi::Function::createFromHostFunction(
|
|
22
|
+
rt,
|
|
23
|
+
jsi::PropNameID::forAscii(rt, "jsi_registerMarkdownWorklet"),
|
|
24
|
+
1,
|
|
25
|
+
[](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value {
|
|
26
|
+
auto parserId = registerMarkdownWorklet(extractShareableOrThrow<ShareableWorklet>(rt, args[0]));
|
|
27
|
+
return jsi::Value(parserId);
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
rt.global().setProperty(rt, "jsi_unregisterMarkdownWorklet", jsi::Function::createFromHostFunction(
|
|
31
|
+
rt,
|
|
32
|
+
jsi::PropNameID::forAscii(rt, "jsi_unregisterMarkdownWorklet"),
|
|
33
|
+
1,
|
|
34
|
+
[](jsi::Runtime &rt, const jsi::Value &thisValue, const jsi::Value *args, size_t count) -> jsi::Value {
|
|
35
|
+
auto parserId = static_cast<int>(args[0].asNumber());
|
|
36
|
+
unregisterMarkdownWorklet(parserId);
|
|
37
|
+
return jsi::Value::undefined();
|
|
38
|
+
}));
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
} // namespace livemarkdown
|
|
43
|
+
} // namespace expensify
|
|
@@ -6,13 +6,37 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _reactNative = require("react-native");
|
|
8
8
|
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
var _reactNativeReanimated = require("react-native-reanimated");
|
|
9
10
|
var _MarkdownTextInputDecoratorViewNativeComponent = _interopRequireDefault(require("./MarkdownTextInputDecoratorViewNativeComponent"));
|
|
10
11
|
var _NativeLiveMarkdownModule = _interopRequireDefault(require("./NativeLiveMarkdownModule"));
|
|
11
12
|
var _styleUtils = require("./styleUtils");
|
|
12
13
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
14
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
14
|
-
|
|
15
|
+
let initialized = false;
|
|
16
|
+
let workletRuntime;
|
|
17
|
+
function initializeLiveMarkdownIfNeeded() {
|
|
18
|
+
if (initialized) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (!_NativeLiveMarkdownModule.default) {
|
|
22
|
+
throw new Error('[react-native-live-markdown] NativeLiveMarkdownModule is not available');
|
|
23
|
+
}
|
|
15
24
|
_NativeLiveMarkdownModule.default.install();
|
|
25
|
+
if (!global.jsi_setMarkdownRuntime) {
|
|
26
|
+
throw new Error('[react-native-live-markdown] global.jsi_setMarkdownRuntime is not available');
|
|
27
|
+
}
|
|
28
|
+
workletRuntime = (0, _reactNativeReanimated.createWorkletRuntime)('LiveMarkdownRuntime');
|
|
29
|
+
global.jsi_setMarkdownRuntime(workletRuntime);
|
|
30
|
+
initialized = true;
|
|
31
|
+
}
|
|
32
|
+
function registerParser(parser) {
|
|
33
|
+
initializeLiveMarkdownIfNeeded();
|
|
34
|
+
const shareableWorklet = (0, _reactNativeReanimated.makeShareableCloneRecursive)(parser);
|
|
35
|
+
const parserId = global.jsi_registerMarkdownWorklet(shareableWorklet);
|
|
36
|
+
return parserId;
|
|
37
|
+
}
|
|
38
|
+
function unregisterParser(parserId) {
|
|
39
|
+
global.jsi_unregisterMarkdownWorklet(parserId);
|
|
16
40
|
}
|
|
17
41
|
function processColorsInMarkdownStyle(input) {
|
|
18
42
|
const output = JSON.parse(JSON.stringify(input));
|
|
@@ -34,11 +58,28 @@ function processMarkdownStyle(input) {
|
|
|
34
58
|
const MarkdownTextInput = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
|
|
35
59
|
const IS_FABRIC = 'nativeFabricUIManager' in global;
|
|
36
60
|
const markdownStyle = _react.default.useMemo(() => processMarkdownStyle(props.markdownStyle), [props.markdownStyle]);
|
|
61
|
+
if (props.parser === undefined) {
|
|
62
|
+
throw new Error('[react-native-live-markdown] `parser` is undefined');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
66
|
+
const workletHash = props.parser.__workletHash;
|
|
67
|
+
if (workletHash === undefined) {
|
|
68
|
+
throw new Error('[react-native-live-markdown] `parser` is not a worklet');
|
|
69
|
+
}
|
|
70
|
+
const parserId = _react.default.useMemo(() => {
|
|
71
|
+
return registerParser(props.parser);
|
|
72
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
73
|
+
}, [workletHash]);
|
|
74
|
+
_react.default.useEffect(() => {
|
|
75
|
+
return () => unregisterParser(parserId);
|
|
76
|
+
}, [parserId]);
|
|
37
77
|
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactNative.TextInput, _extends({}, props, {
|
|
38
78
|
ref: ref
|
|
39
79
|
})), /*#__PURE__*/_react.default.createElement(_MarkdownTextInputDecoratorViewNativeComponent.default, {
|
|
40
80
|
style: IS_FABRIC ? styles.farAway : styles.displayNone,
|
|
41
|
-
markdownStyle: markdownStyle
|
|
81
|
+
markdownStyle: markdownStyle,
|
|
82
|
+
parserId: parserId
|
|
42
83
|
}));
|
|
43
84
|
});
|
|
44
85
|
const styles = _reactNative.StyleSheet.create({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","_react","_interopRequireDefault","_MarkdownTextInputDecoratorViewNativeComponent","_NativeLiveMarkdownModule","_styleUtils","e","__esModule","default","_extends","Object","assign","bind","n","arguments","length","t","r","hasOwnProperty","call","apply","NativeLiveMarkdownModule","install","processColorsInMarkdownStyle","input","output","JSON","parse","stringify","keys","forEach","key","obj","prop","endsWith","processColor","processMarkdownStyle","mergeMarkdownStyleWithDefault","MarkdownTextInput","React","forwardRef","props","ref","IS_FABRIC","
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_react","_interopRequireDefault","_reactNativeReanimated","_MarkdownTextInputDecoratorViewNativeComponent","_NativeLiveMarkdownModule","_styleUtils","e","__esModule","default","_extends","Object","assign","bind","n","arguments","length","t","r","hasOwnProperty","call","apply","initialized","workletRuntime","initializeLiveMarkdownIfNeeded","NativeLiveMarkdownModule","Error","install","global","jsi_setMarkdownRuntime","createWorkletRuntime","registerParser","parser","shareableWorklet","makeShareableCloneRecursive","parserId","jsi_registerMarkdownWorklet","unregisterParser","jsi_unregisterMarkdownWorklet","processColorsInMarkdownStyle","input","output","JSON","parse","stringify","keys","forEach","key","obj","prop","endsWith","processColor","processMarkdownStyle","mergeMarkdownStyleWithDefault","MarkdownTextInput","React","forwardRef","props","ref","IS_FABRIC","markdownStyle","useMemo","undefined","workletHash","__workletHash","useEffect","createElement","Fragment","TextInput","style","styles","farAway","displayNone","StyleSheet","create","display","position","top","left","_default","exports"],"sourceRoot":"../../src","sources":["MarkdownTextInput.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -18,7 +18,6 @@ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return
|
|
|
18
18
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
19
19
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
20
20
|
|
|
21
|
-
require('../parser/react-native-live-markdown-parser.js');
|
|
22
21
|
const useClientEffect = typeof window === 'undefined' ? _react.useEffect : _react.useLayoutEffect;
|
|
23
22
|
let focusTimeout = null;
|
|
24
23
|
const MarkdownTextInput = /*#__PURE__*/_react.default.forwardRef(({
|
|
@@ -34,6 +33,7 @@ const MarkdownTextInput = /*#__PURE__*/_react.default.forwardRef(({
|
|
|
34
33
|
numberOfLines,
|
|
35
34
|
multiline = false,
|
|
36
35
|
markdownStyle,
|
|
36
|
+
parser,
|
|
37
37
|
onBlur,
|
|
38
38
|
onChange,
|
|
39
39
|
onChangeText,
|
|
@@ -58,6 +58,12 @@ const MarkdownTextInput = /*#__PURE__*/_react.default.forwardRef(({
|
|
|
58
58
|
addAuthTokenToImageURLCallback,
|
|
59
59
|
imagePreviewAuthRequiredURLs
|
|
60
60
|
}, ref) => {
|
|
61
|
+
if (parser === undefined) {
|
|
62
|
+
throw new Error('[react-native-live-markdown] `parser` is undefined');
|
|
63
|
+
}
|
|
64
|
+
if (typeof parser !== 'function') {
|
|
65
|
+
throw new Error('[react-native-live-markdown] `parser` is not a function');
|
|
66
|
+
}
|
|
61
67
|
const compositionRef = (0, _react.useRef)(false);
|
|
62
68
|
const divRef = (0, _react.useRef)(null);
|
|
63
69
|
const currentlyFocusedField = (0, _react.useRef)(null);
|
|
@@ -87,7 +93,7 @@ const MarkdownTextInput = /*#__PURE__*/_react.default.forwardRef(({
|
|
|
87
93
|
}
|
|
88
94
|
return e;
|
|
89
95
|
}, []);
|
|
90
|
-
const parseText = (0, _react.useCallback)((target, text, customMarkdownStyles, cursorPosition = null, shouldAddToHistory = true, shouldForceDOMUpdate = false, shouldScrollIntoView = false) => {
|
|
96
|
+
const parseText = (0, _react.useCallback)((parserFunction, target, text, customMarkdownStyles, cursorPosition = null, shouldAddToHistory = true, shouldForceDOMUpdate = false, shouldScrollIntoView = false) => {
|
|
91
97
|
if (!divRef.current) {
|
|
92
98
|
return {
|
|
93
99
|
text: text || '',
|
|
@@ -100,7 +106,7 @@ const MarkdownTextInput = /*#__PURE__*/_react.default.forwardRef(({
|
|
|
100
106
|
cursorPosition: null
|
|
101
107
|
};
|
|
102
108
|
}
|
|
103
|
-
const parsedText = (0, _parserUtils.updateInputStructure)(target, text, cursorPosition, multiline, customMarkdownStyles, false, shouldForceDOMUpdate, shouldScrollIntoView, {
|
|
109
|
+
const parsedText = (0, _parserUtils.updateInputStructure)(parserFunction, target, text, cursorPosition, multiline, customMarkdownStyles, false, shouldForceDOMUpdate, shouldScrollIntoView, {
|
|
104
110
|
addAuthTokenToImageURLCallback,
|
|
105
111
|
imagePreviewAuthRequiredURLs
|
|
106
112
|
});
|
|
@@ -113,10 +119,10 @@ const MarkdownTextInput = /*#__PURE__*/_react.default.forwardRef(({
|
|
|
113
119
|
const processedMarkdownStyle = (0, _react.useMemo)(() => {
|
|
114
120
|
const newMarkdownStyle = (0, _webStyleUtils.processMarkdownStyle)(markdownStyle);
|
|
115
121
|
if (divRef.current) {
|
|
116
|
-
parseText(divRef.current, divRef.current.value, newMarkdownStyle, null, false, false);
|
|
122
|
+
parseText(parser, divRef.current, divRef.current.value, newMarkdownStyle, null, false, false);
|
|
117
123
|
}
|
|
118
124
|
return newMarkdownStyle;
|
|
119
|
-
}, [markdownStyle, parseText]);
|
|
125
|
+
}, [parser, markdownStyle, parseText]);
|
|
120
126
|
const inputStyles = (0, _react.useMemo)(() => _reactNative.StyleSheet.flatten([styles.defaultInputStyles, flattenedStyle && {
|
|
121
127
|
caretColor: flattenedStyle.color || 'black'
|
|
122
128
|
}, {
|
|
@@ -131,8 +137,8 @@ const MarkdownTextInput = /*#__PURE__*/_react.default.forwardRef(({
|
|
|
131
137
|
}
|
|
132
138
|
const item = history.current.undo();
|
|
133
139
|
const undoValue = item ? item.text : null;
|
|
134
|
-
return parseText(target, undoValue, processedMarkdownStyle, item ? item.cursorPosition : null, false);
|
|
135
|
-
}, [parseText, processedMarkdownStyle]);
|
|
140
|
+
return parseText(parser, target, undoValue, processedMarkdownStyle, item ? item.cursorPosition : null, false);
|
|
141
|
+
}, [parser, parseText, processedMarkdownStyle]);
|
|
136
142
|
const redo = (0, _react.useCallback)(target => {
|
|
137
143
|
if (!history.current) {
|
|
138
144
|
return {
|
|
@@ -142,8 +148,8 @@ const MarkdownTextInput = /*#__PURE__*/_react.default.forwardRef(({
|
|
|
142
148
|
}
|
|
143
149
|
const item = history.current.redo();
|
|
144
150
|
const redoValue = item ? item.text : null;
|
|
145
|
-
return parseText(target, redoValue, processedMarkdownStyle, item ? item.cursorPosition : null, false);
|
|
146
|
-
}, [parseText, processedMarkdownStyle]);
|
|
151
|
+
return parseText(parser, target, redoValue, processedMarkdownStyle, item ? item.cursorPosition : null, false);
|
|
152
|
+
}, [parser, parseText, processedMarkdownStyle]);
|
|
147
153
|
|
|
148
154
|
// Placeholder text color logic
|
|
149
155
|
const updateTextColor = (0, _react.useCallback)((node, text) => {
|
|
@@ -255,7 +261,7 @@ const MarkdownTextInput = /*#__PURE__*/_react.default.forwardRef(({
|
|
|
255
261
|
newInputUpdate = redo(divRef.current);
|
|
256
262
|
break;
|
|
257
263
|
default:
|
|
258
|
-
newInputUpdate = parseText(divRef.current, parsedText, processedMarkdownStyle, newCursorPosition, true, !inputType, inputType === 'pasteText');
|
|
264
|
+
newInputUpdate = parseText(parser, divRef.current, parsedText, processedMarkdownStyle, newCursorPosition, true, !inputType, inputType === 'pasteText');
|
|
259
265
|
}
|
|
260
266
|
const {
|
|
261
267
|
text,
|
|
@@ -299,7 +305,7 @@ const MarkdownTextInput = /*#__PURE__*/_react.default.forwardRef(({
|
|
|
299
305
|
onChangeText(text);
|
|
300
306
|
}
|
|
301
307
|
handleContentSizeChange();
|
|
302
|
-
}, [updateTextColor, updateSelection, onChange, onChangeText, handleContentSizeChange, undo, redo, parseText, processedMarkdownStyle, setEventProps, maxLength]);
|
|
308
|
+
}, [parser, updateTextColor, updateSelection, onChange, onChangeText, handleContentSizeChange, undo, redo, parseText, processedMarkdownStyle, setEventProps, maxLength]);
|
|
303
309
|
const insertText = (0, _react.useCallback)((e, text) => {
|
|
304
310
|
if (!contentSelection.current || !divRef.current) {
|
|
305
311
|
return;
|
|
@@ -490,14 +496,14 @@ const MarkdownTextInput = /*#__PURE__*/_react.default.forwardRef(({
|
|
|
490
496
|
return;
|
|
491
497
|
}
|
|
492
498
|
if (value === undefined) {
|
|
493
|
-
parseText(divRef.current, divRef.current.value, processedMarkdownStyle);
|
|
499
|
+
parseText(parser, divRef.current, divRef.current.value, processedMarkdownStyle);
|
|
494
500
|
return;
|
|
495
501
|
}
|
|
496
502
|
const normalizedValue = (0, _inputUtils.normalizeValue)(value);
|
|
497
503
|
divRef.current.value = normalizedValue;
|
|
498
|
-
parseText(divRef.current, normalizedValue, processedMarkdownStyle, null, true, false, true);
|
|
504
|
+
parseText(parser, divRef.current, normalizedValue, processedMarkdownStyle, null, true, false, true);
|
|
499
505
|
updateTextColor(divRef.current, value);
|
|
500
|
-
}, [multiline, processedMarkdownStyle, value, maxLength]);
|
|
506
|
+
}, [parser, multiline, processedMarkdownStyle, value, maxLength]);
|
|
501
507
|
useClientEffect(function adjustHeight() {
|
|
502
508
|
if (!divRef.current || !multiline) {
|
|
503
509
|
return;
|