@expensify/react-native-live-markdown 0.1.273 → 0.1.275

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.
@@ -4,14 +4,16 @@
4
4
 
5
5
  NS_ASSUME_NONNULL_BEGIN
6
6
 
7
+ const NSAttributedStringKey RCTLiveMarkdownTextAttributeName = @"RCTLiveMarkdownText";
8
+
7
9
  const NSAttributedStringKey RCTLiveMarkdownBlockquoteDepthAttributeName = @"RCTLiveMarkdownBlockquoteDepth";
8
10
 
9
11
  @interface MarkdownFormatter : NSObject
10
12
 
11
- - (nonnull NSAttributedString *)format:(nonnull NSString *)text
12
- withDefaultTextAttributes:(nonnull NSDictionary<NSAttributedStringKey, id> *)defaultTextAttributes
13
- withMarkdownRanges:(nonnull NSArray<MarkdownRange *> *)markdownRanges
14
- withMarkdownStyle:(nonnull RCTMarkdownStyle *)markdownStyle;
13
+ - (void)formatAttributedString:(nonnull NSMutableAttributedString *)attributedString
14
+ withDefaultTextAttributes:(nonnull NSDictionary<NSAttributedStringKey, id> *)defaultTextAttributes
15
+ withMarkdownRanges:(nonnull NSArray<MarkdownRange *> *)markdownRanges
16
+ withMarkdownStyle:(nonnull RCTMarkdownStyle *)markdownStyle;
15
17
 
16
18
  NS_ASSUME_NONNULL_END
17
19
 
@@ -3,21 +3,19 @@
3
3
 
4
4
  @implementation MarkdownFormatter
5
5
 
6
- - (nonnull NSAttributedString *)format:(nonnull NSString *)text
7
- withDefaultTextAttributes:(nonnull NSDictionary<NSAttributedStringKey, id> *)defaultTextAttributes
8
- withMarkdownRanges:(nonnull NSArray<MarkdownRange *> *)markdownRanges
9
- withMarkdownStyle:(nonnull RCTMarkdownStyle *)markdownStyle
6
+ - (void)formatAttributedString:(nonnull NSMutableAttributedString *)attributedString
7
+ withDefaultTextAttributes:(nonnull NSDictionary<NSAttributedStringKey, id> *)defaultTextAttributes
8
+ withMarkdownRanges:(nonnull NSArray<MarkdownRange *> *)markdownRanges
9
+ withMarkdownStyle:(nonnull RCTMarkdownStyle *)markdownStyle
10
10
  {
11
- NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text attributes:defaultTextAttributes];
11
+ NSRange fullRange = NSMakeRange(0, attributedString.length);
12
12
 
13
13
  [attributedString beginEditing];
14
14
 
15
- // If the attributed string ends with underlined text, blurring the single-line input imprints the underline style across the whole string.
16
- // It looks like a bug in iOS, as there is no underline style to be found in the attributed string, especially after formatting.
17
- // This is a workaround that applies the NSUnderlineStyleNone to the string before iterating over ranges which resolves this problem.
18
- [attributedString addAttribute:NSUnderlineStyleAttributeName
19
- value:[NSNumber numberWithInteger:NSUnderlineStyleNone]
20
- range:NSMakeRange(0, attributedString.length)];
15
+ [attributedString setAttributes:defaultTextAttributes range:fullRange];
16
+
17
+ // We add a custom attribute to force a different comparison mode in swizzled `_textOf` method.
18
+ [attributedString addAttribute:RCTLiveMarkdownTextAttributeName value:@(YES) range:fullRange];
21
19
 
22
20
  for (MarkdownRange *markdownRange in markdownRanges) {
23
21
  [self applyRangeToAttributedString:attributedString
@@ -28,15 +26,15 @@
28
26
  defaultTextAttributes:defaultTextAttributes];
29
27
  }
30
28
 
31
- [attributedString.string enumerateSubstringsInRange:NSMakeRange(0, attributedString.length)
29
+ [attributedString.string enumerateSubstringsInRange:fullRange
32
30
  options:NSStringEnumerationByLines | NSStringEnumerationSubstringNotRequired
33
31
  usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
34
32
  RCTApplyBaselineOffset(attributedString, enclosingRange);
35
33
  }];
36
34
 
37
- [attributedString endEditing];
35
+ [attributedString fixAttributesInRange:fullRange];
38
36
 
39
- return attributedString;
37
+ [attributedString endEditing];
40
38
  }
41
39
 
42
40
  - (void)applyRangeToAttributedString:(NSMutableAttributedString *)attributedString
@@ -0,0 +1,17 @@
1
+ #import <UIKit/UIKit.h>
2
+ #import <React/RCTUITextField.h>
3
+ #import <RNLiveMarkdown/RCTMarkdownUtils.h>
4
+
5
+ NS_ASSUME_NONNULL_BEGIN
6
+
7
+ @interface MarkdownTextFieldObserver : NSObject
8
+
9
+ - (instancetype)initWithTextField:(nonnull RCTUITextField *)textField markdownUtils:(nonnull RCTMarkdownUtils *)markdownUtils;
10
+
11
+ - (void)textFieldDidChange:(UITextField *)textField;
12
+
13
+ - (void)textFieldDidEndEditing:(UITextField *)textField;
14
+
15
+ @end
16
+
17
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,73 @@
1
+ #import <RNLiveMarkdown/MarkdownTextFieldObserver.h>
2
+ #import "react_native_assert.h"
3
+
4
+ @implementation MarkdownTextFieldObserver {
5
+ RCTUITextField *_textField;
6
+ RCTMarkdownUtils *_markdownUtils;
7
+ BOOL _active;
8
+ }
9
+
10
+ - (instancetype)initWithTextField:(nonnull RCTUITextField *)textField markdownUtils:(nonnull RCTMarkdownUtils *)markdownUtils
11
+ {
12
+ if ((self = [super init])) {
13
+ react_native_assert(textField != nil);
14
+ react_native_assert(markdownUtils != nil);
15
+
16
+ _textField = textField;
17
+ _markdownUtils = markdownUtils;
18
+ _active = YES;
19
+ }
20
+ return self;
21
+ }
22
+
23
+ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
24
+ {
25
+ if (_active && ([keyPath isEqualToString:@"text"] || [keyPath isEqualToString:@"attributedText"])) {
26
+ [self applyMarkdownFormatting];
27
+ }
28
+ }
29
+
30
+ - (void)textFieldDidChange:(__unused UITextField *)textField
31
+ {
32
+ [self applyMarkdownFormatting];
33
+ }
34
+
35
+ - (void)textFieldDidEndEditing:(__unused UITextField *)textField
36
+ {
37
+ // In order to prevent iOS from applying underline to the whole text if text ends with a link on blur,
38
+ // we need to update `defaultTextAttributes` which at this point doesn't contain NSUnderline attribute yet.
39
+ // It seems like the setter performs deep comparision, so we differentiate the new value using a counter,
40
+ // otherwise this trick would work only once.
41
+ static NSAttributedStringKey RCTLiveMarkdownForceUpdateAttributeName = @"RCTLiveMarkdownForceUpdate";
42
+ static NSUInteger counter = 0;
43
+ NSMutableDictionary *defaultTextAttributes = [_textField.defaultTextAttributes mutableCopy];
44
+ defaultTextAttributes[RCTLiveMarkdownForceUpdateAttributeName] = @(counter++);
45
+ _textField.defaultTextAttributes = defaultTextAttributes;
46
+ [self applyMarkdownFormatting];
47
+ }
48
+
49
+ - (void)applyMarkdownFormatting
50
+ {
51
+ react_native_assert(_textField.defaultTextAttributes != nil);
52
+
53
+ if (_textField.markedTextRange != nil) {
54
+ return; // skip formatting during multi-stage input to avoid breaking internal state
55
+ }
56
+
57
+ NSMutableAttributedString *attributedText = [_textField.attributedText mutableCopy];
58
+ [_markdownUtils applyMarkdownFormatting:attributedText withDefaultTextAttributes:_textField.defaultTextAttributes];
59
+
60
+ UITextRange *textRange = _textField.selectedTextRange;
61
+
62
+ _active = NO; // prevent recursion
63
+ _textField.attributedText = attributedText;
64
+ _active = YES;
65
+
66
+ // Restore cursor position
67
+ [_textField setSelectedTextRange:textRange notifyDelegate:NO];
68
+
69
+ // Eliminate underline blinks while typing if previous text ends with a link
70
+ _textField.typingAttributes = _textField.defaultTextAttributes;
71
+ }
72
+
73
+ @end
@@ -2,15 +2,17 @@
2
2
  #import <react/renderer/components/RNLiveMarkdownSpec/Props.h>
3
3
  #import <React/RCTFabricComponentsPlugins.h>
4
4
  #import <React/RCTUITextField.h>
5
+ #import <React/RCTUITextView.h>
6
+ #import <React/RCTTextInputComponentView.h>
5
7
 
6
8
  #import <RNLiveMarkdown/MarkdownBackedTextInputDelegate.h>
7
9
  #import <RNLiveMarkdown/MarkdownLayoutManager.h>
10
+ #import <RNLiveMarkdown/MarkdownTextFieldObserver.h>
11
+ #import <RNLiveMarkdown/MarkdownTextViewObserver.h>
8
12
  #import <RNLiveMarkdown/MarkdownTextInputDecoratorComponentView.h>
9
13
  #import <RNLiveMarkdown/MarkdownTextInputDecoratorViewComponentDescriptor.h>
10
- #import <RNLiveMarkdown/RCTBackedTextFieldDelegateAdapter+Markdown.h>
14
+ #import <RNLiveMarkdown/MarkdownTextStorageDelegate.h>
11
15
  #import <RNLiveMarkdown/RCTMarkdownStyle.h>
12
- #import <RNLiveMarkdown/RCTTextInputComponentView+Markdown.h>
13
- #import <RNLiveMarkdown/RCTUITextView+Markdown.h>
14
16
 
15
17
  #import <objc/runtime.h>
16
18
 
@@ -21,10 +23,11 @@ using namespace facebook::react;
21
23
  RCTMarkdownStyle *_markdownStyle;
22
24
  NSNumber *_parserId;
23
25
  MarkdownBackedTextInputDelegate *_markdownBackedTextInputDelegate;
24
- __weak RCTTextInputComponentView *_textInput;
25
- __weak UIView<RCTBackedTextInputViewProtocol> *_backedTextInputView;
26
- __weak RCTBackedTextFieldDelegateAdapter *_adapter;
26
+ MarkdownTextStorageDelegate *_markdownTextStorageDelegate;
27
+ MarkdownTextViewObserver *_markdownTextViewObserver;
28
+ MarkdownTextFieldObserver *_markdownTextFieldObserver;
27
29
  __weak RCTUITextView *_textView;
30
+ __weak RCTUITextField *_textField;
28
31
  }
29
32
 
30
33
  + (ComponentDescriptorProvider)componentDescriptorProvider
@@ -51,21 +54,47 @@ using namespace facebook::react;
51
54
  - (void)didAddSubview:(UIView *)subview
52
55
  {
53
56
  react_native_assert([subview isKindOfClass:[RCTTextInputComponentView class]] && "Child component of MarkdownTextInputDecoratorComponentView is not an instance of RCTTextInputComponentView.");
54
- _textInput = (RCTTextInputComponentView *)subview;
55
- _backedTextInputView = [_textInput valueForKey:@"_backedTextInputView"];
57
+ RCTTextInputComponentView *textInputComponentView = (RCTTextInputComponentView *)subview;
58
+ UIView<RCTBackedTextInputViewProtocol> *backedTextInputView = [textInputComponentView valueForKey:@"_backedTextInputView"];
56
59
 
57
60
  _markdownUtils = [[RCTMarkdownUtils alloc] init];
58
61
  [_markdownUtils setMarkdownStyle:_markdownStyle];
59
62
  [_markdownUtils setParserId:_parserId];
60
63
 
61
- [_textInput setMarkdownUtils:_markdownUtils];
62
- if ([_backedTextInputView isKindOfClass:[RCTUITextField class]]) {
63
- RCTUITextField *textField = (RCTUITextField *)_backedTextInputView;
64
- _adapter = [textField valueForKey:@"textInputDelegateAdapter"];
65
- [_adapter setMarkdownUtils:_markdownUtils];
66
- } else if ([_backedTextInputView isKindOfClass:[RCTUITextView class]]) {
67
- _textView = (RCTUITextView *)_backedTextInputView;
68
- [_textView setMarkdownUtils:_markdownUtils];
64
+ if ([backedTextInputView isKindOfClass:[RCTUITextField class]]) {
65
+ _textField = (RCTUITextField *)backedTextInputView;
66
+
67
+ // make sure `adjustsFontSizeToFitWidth` is disabled, otherwise formatting will be overwritten
68
+ react_native_assert(_textField.adjustsFontSizeToFitWidth == NO);
69
+
70
+ _markdownTextFieldObserver = [[MarkdownTextFieldObserver alloc] initWithTextField:_textField markdownUtils:_markdownUtils];
71
+
72
+ // register observers for future edits
73
+ [_textField addTarget:_markdownTextFieldObserver action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
74
+ [_textField addTarget:_markdownTextFieldObserver action:@selector(textFieldDidEndEditing:) forControlEvents:UIControlEventEditingDidEnd];
75
+ [_textField addObserver:_markdownTextFieldObserver forKeyPath:@"text" options:NSKeyValueObservingOptionNew context:NULL];
76
+ [_textField addObserver:_markdownTextFieldObserver forKeyPath:@"attributedText" options:NSKeyValueObservingOptionNew context:NULL];
77
+
78
+ // format initial value
79
+ [_markdownTextFieldObserver textFieldDidChange:_textField];
80
+
81
+ // TODO: register blockquotes layout manager
82
+ // https://github.com/Expensify/react-native-live-markdown/issues/87
83
+ } else if ([backedTextInputView isKindOfClass:[RCTUITextView class]]) {
84
+ _textView = (RCTUITextView *)backedTextInputView;
85
+
86
+ // register delegate for future edits
87
+ react_native_assert(_textView.textStorage.delegate == nil);
88
+ _markdownTextStorageDelegate = [[MarkdownTextStorageDelegate alloc] initWithTextView:_textView markdownUtils:_markdownUtils];
89
+ _textView.textStorage.delegate = _markdownTextStorageDelegate;
90
+
91
+ // register observer for default text attributes
92
+ _markdownTextViewObserver = [[MarkdownTextViewObserver alloc] initWithTextView:_textView markdownUtils:_markdownUtils];
93
+ [_textView addObserver:_markdownTextViewObserver forKeyPath:@"defaultTextAttributes" options:NSKeyValueObservingOptionNew context:NULL];
94
+
95
+ // format initial value
96
+ [_textView.textStorage setAttributedString:_textView.attributedText];
97
+
69
98
  NSLayoutManager *layoutManager = _textView.layoutManager; // switching to TextKit 1 compatibility mode
70
99
 
71
100
  // Correct content height in TextKit 1 compatibility mode. (See https://github.com/Expensify/App/issues/41567)
@@ -91,19 +120,26 @@ using namespace facebook::react;
91
120
  if (newWindow != nil) {
92
121
  return;
93
122
  }
94
- if (_textInput != nil) {
95
- [_textInput setMarkdownUtils:nil];
96
- }
97
- if (_adapter != nil) {
98
- [_adapter setMarkdownUtils:nil];
99
- }
100
123
  if (_textView != nil) {
101
- _markdownBackedTextInputDelegate = nil;
102
- [_textView setMarkdownUtils:nil];
103
124
  if (_textView.layoutManager != nil && [object_getClass(_textView.layoutManager) isEqual:[MarkdownLayoutManager class]]) {
104
125
  [_textView.layoutManager setValue:nil forKey:@"markdownUtils"];
105
126
  object_setClass(_textView.layoutManager, [NSLayoutManager class]);
106
127
  }
128
+ _markdownBackedTextInputDelegate = nil;
129
+ [_textView removeObserver:_markdownTextViewObserver forKeyPath:@"defaultTextAttributes" context:NULL];
130
+ _markdownTextViewObserver = nil;
131
+ _markdownTextStorageDelegate = nil;
132
+ _textView.textStorage.delegate = nil;
133
+ _textView = nil;
134
+ }
135
+
136
+ if (_textField != nil) {
137
+ [_textField removeTarget:_markdownTextFieldObserver action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
138
+ [_textField removeTarget:_markdownTextFieldObserver action:@selector(textFieldDidEndEditing:) forControlEvents:UIControlEventEditingDidEnd];
139
+ [_textField removeObserver:_markdownTextFieldObserver forKeyPath:@"text" context:NULL];
140
+ [_textField removeObserver:_markdownTextFieldObserver forKeyPath:@"attributedText" context:NULL];
141
+ _markdownTextFieldObserver = nil;
142
+ _textField = nil;
107
143
  }
108
144
  }
109
145
 
@@ -130,11 +166,10 @@ using namespace facebook::react;
130
166
  - (void)applyNewStyles
131
167
  {
132
168
  if (_textView != nil) {
133
- // We want to use `textStorage` for applying markdown when possible. Currently it's only available for UITextView
134
- [_textView textDidChange];
135
- } else {
136
- // apply new styles
137
- [_textInput _setAttributedString:_backedTextInputView.attributedText];
169
+ [_textView.textStorage setAttributedString:_textView.attributedText];
170
+ }
171
+ if (_textField != nil) {
172
+ [_markdownTextFieldObserver textFieldDidChange:_textField];
138
173
  }
139
174
  }
140
175
 
@@ -188,8 +188,8 @@ void MarkdownTextInputDecoratorShadowNode::applyMarkdownFormattingToTextInputSta
188
188
  }
189
189
 
190
190
  // apply markdown
191
- auto newString = [utils parseMarkdown:nsAttributedString
192
- withDefaultTextAttributes:defaultNSTextAttributes];
191
+ NSMutableAttributedString *newString = [nsAttributedString mutableCopy];
192
+ [utils applyMarkdownFormatting:newString withDefaultTextAttributes:defaultNSTextAttributes];
193
193
 
194
194
  // create a clone of the old TextInputState and update the
195
195
  // attributed string box to point to the string with markdown
@@ -200,8 +200,8 @@ void MarkdownTextInputDecoratorShadowNode::applyMarkdownFormattingToTextInputSta
200
200
  AttributedStringBox::Mode::OpaquePointer) {
201
201
 
202
202
  // apply markdown
203
- auto newString = [utils parseMarkdown:nsAttributedString
204
- withDefaultTextAttributes:defaultNSTextAttributes];
203
+ NSMutableAttributedString *newString = [nsAttributedString mutableCopy];
204
+ [utils applyMarkdownFormatting:newString withDefaultTextAttributes:defaultNSTextAttributes];
205
205
 
206
206
  // create a clone of the old TextInputState and update the
207
207
  // attributed string box to point to the string with markdown
@@ -0,0 +1,13 @@
1
+ #import <UIKit/UIKit.h>
2
+ #import <React/RCTUITextView.h>
3
+ #import <RNLiveMarkdown/RCTMarkdownUtils.h>
4
+
5
+ NS_ASSUME_NONNULL_BEGIN
6
+
7
+ @interface MarkdownTextStorageDelegate : NSObject <NSTextStorageDelegate>
8
+
9
+ - (instancetype)initWithTextView:(nonnull RCTUITextView *)textView markdownUtils:(nonnull RCTMarkdownUtils *)markdownUtils;
10
+
11
+ @end
12
+
13
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,27 @@
1
+ #import <RNLiveMarkdown/MarkdownTextStorageDelegate.h>
2
+ #import "react_native_assert.h"
3
+
4
+ @implementation MarkdownTextStorageDelegate {
5
+ RCTUITextView *_textView;
6
+ RCTMarkdownUtils *_markdownUtils;
7
+ }
8
+
9
+ - (instancetype)initWithTextView:(nonnull RCTUITextView *)textView markdownUtils:(nonnull RCTMarkdownUtils *)markdownUtils
10
+ {
11
+ if ((self = [super init])) {
12
+ react_native_assert(textView != nil);
13
+ react_native_assert(markdownUtils != nil);
14
+
15
+ _textView = textView;
16
+ _markdownUtils = markdownUtils;
17
+ }
18
+ return self;
19
+ }
20
+
21
+ - (void)textStorage:(NSTextStorage *)textStorage didProcessEditing:(NSTextStorageEditActions)editedMask range:(NSRange)editedRange changeInLength:(NSInteger)delta {
22
+ react_native_assert(_textView.defaultTextAttributes != nil);
23
+
24
+ [_markdownUtils applyMarkdownFormatting:textStorage withDefaultTextAttributes:_textView.defaultTextAttributes];
25
+ }
26
+
27
+ @end
@@ -0,0 +1,13 @@
1
+ #import <UIKit/UIKit.h>
2
+ #import <React/RCTUITextView.h>
3
+ #import <RNLiveMarkdown/RCTMarkdownUtils.h>
4
+
5
+ NS_ASSUME_NONNULL_BEGIN
6
+
7
+ @interface MarkdownTextViewObserver : NSObject
8
+
9
+ - (instancetype)initWithTextView:(nonnull RCTUITextView *)textView markdownUtils:(nonnull RCTMarkdownUtils *)markdownUtils;
10
+
11
+ @end
12
+
13
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,28 @@
1
+ #import <RNLiveMarkdown/MarkdownTextViewObserver.h>
2
+ #import "react_native_assert.h"
3
+
4
+ @implementation MarkdownTextViewObserver {
5
+ RCTUITextView *_textView;
6
+ RCTMarkdownUtils *_markdownUtils;
7
+ }
8
+
9
+ - (instancetype)initWithTextView:(nonnull RCTUITextView *)textView markdownUtils:(nonnull RCTMarkdownUtils *)markdownUtils
10
+ {
11
+ if ((self = [super init])) {
12
+ react_native_assert(textView != nil);
13
+ react_native_assert(markdownUtils != nil);
14
+
15
+ _textView = textView;
16
+ _markdownUtils = markdownUtils;
17
+ }
18
+ return self;
19
+ }
20
+
21
+ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
22
+ {
23
+ if ([keyPath isEqualToString:@"defaultTextAttributes"]) {
24
+ [_textView.textStorage setAttributedString:_textView.attributedText];
25
+ }
26
+ }
27
+
28
+ @end
@@ -8,8 +8,8 @@ NS_ASSUME_NONNULL_BEGIN
8
8
  @property (nonatomic) RCTMarkdownStyle *markdownStyle;
9
9
  @property (nonatomic) NSNumber *parserId;
10
10
 
11
- - (NSAttributedString *)parseMarkdown:(nullable NSAttributedString *)input
12
- withDefaultTextAttributes:(nonnull NSDictionary<NSAttributedStringKey, id> *)defaultTextAttributes;
11
+ - (void)applyMarkdownFormatting:(nonnull NSMutableAttributedString *)attributedString
12
+ withDefaultTextAttributes:(nonnull NSDictionary<NSAttributedStringKey, id> *)defaultTextAttributes;
13
13
 
14
14
  @end
15
15
 
@@ -5,11 +5,6 @@
5
5
  @implementation RCTMarkdownUtils {
6
6
  MarkdownParser *_markdownParser;
7
7
  MarkdownFormatter *_markdownFormatter;
8
- NSString *_prevInputString;
9
- NSAttributedString *_prevAttributedString;
10
- NSDictionary<NSAttributedStringKey, id> *_prevDefaultTextAttributes;
11
- __weak RCTMarkdownStyle *_prevMarkdownStyle;
12
- __weak NSNumber *_prevParserId;
13
8
  }
14
9
 
15
10
  - (instancetype)init
@@ -22,39 +17,21 @@
22
17
  return self;
23
18
  }
24
19
 
25
- - (NSAttributedString *)parseMarkdown:(nullable NSAttributedString *)input
26
- withDefaultTextAttributes:(nonnull NSDictionary<NSAttributedStringKey, id> *)defaultTextAttributes
20
+ - (void)applyMarkdownFormatting:(nonnull NSMutableAttributedString *)attributedString
21
+ withDefaultTextAttributes:(nonnull NSDictionary<NSAttributedStringKey, id> *)defaultTextAttributes
27
22
  {
28
- @synchronized (self) {
29
- if (input == nil) {
30
- return nil;
31
- }
32
-
33
- // `_markdownStyle` and `_parserId` may not be initialized immediately due to the order of mount instructions
34
- // props update will be executed after the view hierarchy is initialized.
35
- if (_markdownStyle == nil || _parserId == nil) {
36
- return nil;
37
- }
38
-
39
- NSString *inputString = [input string];
40
- if ([inputString isEqualToString:_prevInputString] && [defaultTextAttributes isEqualToDictionary:_prevDefaultTextAttributes] && [_markdownStyle isEqual:_prevMarkdownStyle] && [_parserId isEqualToNumber:_prevParserId]) {
41
- return _prevAttributedString;
42
- }
43
-
44
- NSArray<MarkdownRange *> *markdownRanges = [_markdownParser parse:inputString withParserId:_parserId];
23
+ // `_markdownStyle` and `_parserId` may not be initialized immediately due to the order of mount instructions
24
+ // props update will be executed after the view hierarchy is initialized.
25
+ if (_markdownStyle == nil || _parserId == nil) {
26
+ return;
27
+ }
45
28
 
46
- NSAttributedString *attributedString = [_markdownFormatter format:inputString
47
- withDefaultTextAttributes:defaultTextAttributes
48
- withMarkdownRanges:markdownRanges
49
- withMarkdownStyle:_markdownStyle];
50
- _prevInputString = inputString;
51
- _prevAttributedString = attributedString;
52
- _prevDefaultTextAttributes = defaultTextAttributes;
53
- _prevMarkdownStyle = _markdownStyle;
54
- _prevParserId = _parserId;
29
+ NSArray<MarkdownRange *> *markdownRanges = [_markdownParser parse:attributedString.string withParserId:_parserId];
55
30
 
56
- return attributedString;
57
- }
31
+ [_markdownFormatter formatAttributedString:attributedString
32
+ withDefaultTextAttributes:defaultTextAttributes
33
+ withMarkdownRanges:markdownRanges
34
+ withMarkdownStyle:_markdownStyle];
58
35
  }
59
36
 
60
37
  @end
@@ -1,18 +1,11 @@
1
1
  #import <React/RCTTextInputComponentView.h>
2
- #import <RNLiveMarkdown/RCTMarkdownUtils.h>
3
2
 
4
3
  NS_ASSUME_NONNULL_BEGIN
5
4
 
6
5
  @interface RCTTextInputComponentView (Markdown)
7
6
 
8
- @property(nonatomic, nullable, getter=getMarkdownUtils) RCTMarkdownUtils *markdownUtils;
9
-
10
- - (void)markdown__setAttributedString:(NSAttributedString *)attributedString;
11
-
12
7
  - (BOOL)markdown__textOf:(NSAttributedString *)newText equals:(NSAttributedString *)oldText;
13
8
 
14
- - (void)_setAttributedString:(NSAttributedString *)attributedString;
15
-
16
9
  @end
17
10
 
18
11
  NS_ASSUME_NONNULL_END
@@ -1,63 +1,23 @@
1
1
  #import <RNLiveMarkdown/RCTTextInputComponentView+Markdown.h>
2
- #import <RNLiveMarkdown/RCTMarkdownUtils.h>
3
- #import <React/RCTUITextView.h>
2
+ #import <RNLiveMarkdown/MarkdownFormatter.h>
4
3
  #import <objc/message.h>
5
4
 
6
5
  @implementation RCTTextInputComponentView (Markdown)
7
6
 
8
- - (void)setMarkdownUtils:(RCTMarkdownUtils *)markdownUtils {
9
- objc_setAssociatedObject(self, @selector(getMarkdownUtils), markdownUtils, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
10
- }
11
-
12
- - (RCTMarkdownUtils *)getMarkdownUtils {
13
- return objc_getAssociatedObject(self, @selector(getMarkdownUtils));
14
- }
15
-
16
- - (RCTUITextView *)getBackedTextInputView {
17
- return [self valueForKey:@"_backedTextInputView"];
18
- }
19
-
20
- - (void)markdown__setAttributedString:(NSAttributedString *)attributedString
21
- {
22
- RCTMarkdownUtils *markdownUtils = [self getMarkdownUtils];
23
- RCTUITextView *backedTextInputView = [self getBackedTextInputView];
24
- if (markdownUtils != nil && backedTextInputView != nil) {
25
- attributedString = [markdownUtils parseMarkdown:attributedString withDefaultTextAttributes:backedTextInputView.defaultTextAttributes];
26
- }
27
-
28
- // Call the original method
29
- [self markdown__setAttributedString:attributedString];
30
-
31
- if (markdownUtils != nil && backedTextInputView != nil) {
32
- // After adding a newline at the end of the blockquote, the typing attributes in the next line still contain
33
- // NSParagraphStyle with non-zero firstLineHeadIndent and headIntent added by `_updateTypingAttributes` call.
34
- // This causes the cursor to be shifted to the right instead of being located at the beginning of the line.
35
- // The following code resets firstLineHeadIndent and headIndent in NSParagraphStyle in typing attributes
36
- // in order to fix the position of the cursor.
37
- NSDictionary<NSAttributedStringKey, id> *typingAttributes = backedTextInputView.typingAttributes;
38
- if (typingAttributes[NSParagraphStyleAttributeName] != nil) {
39
- NSMutableDictionary *mutableTypingAttributes = [typingAttributes mutableCopy];
40
- NSMutableParagraphStyle *mutableParagraphStyle = [typingAttributes[NSParagraphStyleAttributeName] mutableCopy];
41
- mutableParagraphStyle.firstLineHeadIndent = 0;
42
- mutableParagraphStyle.headIndent = 0;
43
- mutableTypingAttributes[NSParagraphStyleAttributeName] = mutableParagraphStyle;
44
- backedTextInputView.typingAttributes = mutableTypingAttributes;
45
- }
46
- }
47
- }
48
-
49
7
  - (BOOL)markdown__textOf:(NSAttributedString *)newText equals:(NSAttributedString *)oldText
50
8
  {
51
- RCTMarkdownUtils *markdownUtils = [self getMarkdownUtils];
52
- if (markdownUtils != nil) {
53
- // Emoji characters are automatically assigned an AppleColorEmoji NSFont and the original font is moved to NSOriginalFont
54
- // We need to remove these attributes before comparison
55
- NSMutableAttributedString *newTextCopy = [newText mutableCopy];
56
- NSMutableAttributedString *oldTextCopy = [oldText mutableCopy];
57
- [newTextCopy removeAttribute:@"NSFont" range:NSMakeRange(0, newTextCopy.length)];
58
- [oldTextCopy removeAttribute:@"NSFont" range:NSMakeRange(0, oldTextCopy.length)];
59
- [oldTextCopy removeAttribute:@"NSOriginalFont" range:NSMakeRange(0, oldTextCopy.length)];
60
- return [newTextCopy isEqualToAttributedString:oldTextCopy];
9
+ __block BOOL isMarkdownTextInput = false;
10
+ [oldText enumerateAttribute:RCTLiveMarkdownTextAttributeName
11
+ inRange:NSMakeRange(0, oldText.length)
12
+ options:0
13
+ usingBlock:^(id value, NSRange range, BOOL *stop) {
14
+ if (value) {
15
+ isMarkdownTextInput = true;
16
+ *stop = YES;
17
+ }
18
+ }];
19
+ if (isMarkdownTextInput) {
20
+ return [newText.string isEqualToString:oldText.string];
61
21
  }
62
22
 
63
23
  return [self markdown__textOf:newText equals:oldText];
@@ -67,25 +27,13 @@
67
27
  {
68
28
  static dispatch_once_t onceToken;
69
29
  dispatch_once(&onceToken, ^{
70
- {
71
- // swizzle _setAttributedString
72
- Class cls = [self class];
73
- SEL originalSelector = @selector(_setAttributedString:);
74
- SEL swizzledSelector = @selector(markdown__setAttributedString:);
75
- Method originalMethod = class_getInstanceMethod(cls, originalSelector);
76
- Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector);
77
- method_exchangeImplementations(originalMethod, swizzledMethod);
78
- }
79
-
80
- {
81
- // swizzle _textOf
82
- Class cls = [self class];
83
- SEL originalSelector = @selector(_textOf:equals:);
84
- SEL swizzledSelector = @selector(markdown__textOf:equals:);
85
- Method originalMethod = class_getInstanceMethod(cls, originalSelector);
86
- Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector);
87
- method_exchangeImplementations(originalMethod, swizzledMethod);
88
- }
30
+ // swizzle _textOf
31
+ Class cls = [self class];
32
+ SEL originalSelector = @selector(_textOf:equals:);
33
+ SEL swizzledSelector = @selector(markdown__textOf:equals:);
34
+ Method originalMethod = class_getInstanceMethod(cls, originalSelector);
35
+ Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector);
36
+ method_exchangeImplementations(originalMethod, swizzledMethod);
89
37
  });
90
38
  }
91
39
 
@@ -69,8 +69,9 @@ function parseInnerHTMLToText(target, cursorPosition, inputType) {
69
69
  // If we are operating on the nodes that are children of the MarkdownTextInputElement, we need to add a newline after each
70
70
  const isTopComponent = ((_node$parentElement = node.parentElement) === null || _node$parentElement === void 0 ? void 0 : _node$parentElement.contentEditable) === 'true';
71
71
  if (isTopComponent) {
72
- // Replaced text is beeing added as text node, so we need to not add the newline before and after it
73
- if (node.nodeType === Node.TEXT_NODE) {
72
+ // When inputType is undefined, the first part of the replaced text is added as a text node.
73
+ // Because of it, we need to prevent adding new lines in this case
74
+ if (!inputType && node.nodeType === Node.TEXT_NODE) {
74
75
  shouldAddNewline = false;
75
76
  } else {
76
77
  var _firstChild$getAttrib;
@@ -1 +1 @@
1
- {"version":3,"names":["ZERO_WIDTH_SPACE","isEventComposing","nativeEvent","isComposing","keyCode","getPlaceholderValue","placeholder","length","getElementHeight","node","styles","numberOfLines","tempElement","document","createElement","setAttribute","Object","assign","style","textContent","Array","fill","join","parentElement","appendChild","height","clientHeight","removeChild","normalizeValue","value","replaceAll","parseInnerHTMLToText","target","cursorPosition","inputType","getTopParentNode","currentParentNode","parentNode","includes","_currentParentNode$pa","getAttribute","_currentParentNode","stack","text","shouldAddNewline","lastNode","childNodes","nodeName","innerHTML","_node$parentElement","pop","isTopComponent","contentEditable","nodeType","Node","TEXT_NODE","_firstChild$getAttrib","firstChild","containsEmptyBlockElement","call","_parentNode$parentEle","i","child","push","slice"],"sourceRoot":"../../../../src","sources":["web/utils/inputUtils.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["ZERO_WIDTH_SPACE","isEventComposing","nativeEvent","isComposing","keyCode","getPlaceholderValue","placeholder","length","getElementHeight","node","styles","numberOfLines","tempElement","document","createElement","setAttribute","Object","assign","style","textContent","Array","fill","join","parentElement","appendChild","height","clientHeight","removeChild","normalizeValue","value","replaceAll","parseInnerHTMLToText","target","cursorPosition","inputType","getTopParentNode","currentParentNode","parentNode","includes","_currentParentNode$pa","getAttribute","_currentParentNode","stack","text","shouldAddNewline","lastNode","childNodes","nodeName","innerHTML","_node$parentElement","pop","isTopComponent","contentEditable","nodeType","Node","TEXT_NODE","_firstChild$getAttrib","firstChild","containsEmptyBlockElement","call","_parentNode$parentEle","i","child","push","slice"],"sourceRoot":"../../../../src","sources":["web/utils/inputUtils.ts"],"mappings":"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","ignoreList":[]}
@@ -59,8 +59,9 @@ function parseInnerHTMLToText(target, cursorPosition, inputType) {
59
59
  // If we are operating on the nodes that are children of the MarkdownTextInputElement, we need to add a newline after each
60
60
  const isTopComponent = ((_node$parentElement = node.parentElement) === null || _node$parentElement === void 0 ? void 0 : _node$parentElement.contentEditable) === 'true';
61
61
  if (isTopComponent) {
62
- // Replaced text is beeing added as text node, so we need to not add the newline before and after it
63
- if (node.nodeType === Node.TEXT_NODE) {
62
+ // When inputType is undefined, the first part of the replaced text is added as a text node.
63
+ // Because of it, we need to prevent adding new lines in this case
64
+ if (!inputType && node.nodeType === Node.TEXT_NODE) {
64
65
  shouldAddNewline = false;
65
66
  } else {
66
67
  var _firstChild$getAttrib;
@@ -1 +1 @@
1
- {"version":3,"names":["ZERO_WIDTH_SPACE","isEventComposing","nativeEvent","isComposing","keyCode","getPlaceholderValue","placeholder","length","getElementHeight","node","styles","numberOfLines","tempElement","document","createElement","setAttribute","Object","assign","style","textContent","Array","fill","join","parentElement","appendChild","height","clientHeight","removeChild","normalizeValue","value","replaceAll","parseInnerHTMLToText","target","cursorPosition","inputType","getTopParentNode","currentParentNode","parentNode","includes","_currentParentNode$pa","getAttribute","_currentParentNode","stack","text","shouldAddNewline","lastNode","childNodes","nodeName","innerHTML","_node$parentElement","pop","isTopComponent","contentEditable","nodeType","Node","TEXT_NODE","_firstChild$getAttrib","firstChild","containsEmptyBlockElement","call","_parentNode$parentEle","i","child","push","slice"],"sourceRoot":"../../../../src","sources":["web/utils/inputUtils.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["ZERO_WIDTH_SPACE","isEventComposing","nativeEvent","isComposing","keyCode","getPlaceholderValue","placeholder","length","getElementHeight","node","styles","numberOfLines","tempElement","document","createElement","setAttribute","Object","assign","style","textContent","Array","fill","join","parentElement","appendChild","height","clientHeight","removeChild","normalizeValue","value","replaceAll","parseInnerHTMLToText","target","cursorPosition","inputType","getTopParentNode","currentParentNode","parentNode","includes","_currentParentNode$pa","getAttribute","_currentParentNode","stack","text","shouldAddNewline","lastNode","childNodes","nodeName","innerHTML","_node$parentElement","pop","isTopComponent","contentEditable","nodeType","Node","TEXT_NODE","_firstChild$getAttrib","firstChild","containsEmptyBlockElement","call","_parentNode$parentEle","i","child","push","slice"],"sourceRoot":"../../../../src","sources":["web/utils/inputUtils.ts"],"mappings":"AAGA,MAAMA,gBAAgB,GAAG,QAAQ;;AAEjC;AACA;AACA,SAASC,gBAAgBA,CAACC,WAA2D,EAAE;EACrF,OAAOA,WAAW,CAACC,WAAW,IAAID,WAAW,CAACE,OAAO,KAAK,GAAG;AAC/D;AAEA,SAASC,mBAAmBA,CAACC,WAA+B,EAAE;EAC5D,IAAI,CAACA,WAAW,EAAE;IAChB,OAAON,gBAAgB;EACzB;EACA,OAAOM,WAAW,CAACC,MAAM,GAAGD,WAAW,GAAGN,gBAAgB;AAC5D;AAEA,SAASQ,gBAAgBA,CAACC,IAAoB,EAAEC,MAAqB,EAAEC,aAAiC,EAAE;EACxG,IAAIA,aAAa,EAAE;IACjB,MAAMC,WAAW,GAAGC,QAAQ,CAACC,aAAa,CAAC,KAAK,CAAC;IACjDF,WAAW,CAACG,YAAY,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnDC,MAAM,CAACC,MAAM,CAACL,WAAW,CAACM,KAAK,EAAER,MAAM,CAAC;IACxCE,WAAW,CAACO,WAAW,GAAGC,KAAK,CAACT,aAAa,CAAC,CAACU,IAAI,CAAC,GAAG,CAAC,CAACC,IAAI,CAAC,IAAI,CAAC;IACnE,IAAIb,IAAI,CAACc,aAAa,EAAE;MACtBd,IAAI,CAACc,aAAa,CAACC,WAAW,CAACZ,WAAW,CAAC;MAC3C,MAAMa,MAAM,GAAGb,WAAW,CAACc,YAAY;MACvCjB,IAAI,CAACc,aAAa,CAACI,WAAW,CAACf,WAAW,CAAC;MAC3C,OAAOa,MAAM,GAAG,GAAGA,MAAM,IAAI,GAAG,MAAM;IACxC;EACF;EACA,OAAOf,MAAM,CAACe,MAAM,GAAG,GAAGf,MAAM,CAACe,MAAM,IAAI,GAAG,MAAM;AACtD;AAEA,SAASG,cAAcA,CAACC,KAAa,EAAE;EACrC,OAAOA,KAAK,CAACC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC;AACvC;;AAEA;AACA,SAASC,oBAAoBA,CAACC,MAAgC,EAAEC,cAAsB,EAAEC,SAAkB,EAAU;EAClH;EACA,SAASC,gBAAgBA,CAAC1B,IAAe,EAAE;IACzC,IAAI2B,iBAAiB,GAAG3B,IAAI,CAAC4B,UAAU;IACvC,OAAOD,iBAAiB,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAACE,QAAQ,CAAC,EAAAC,qBAAA,GAAAH,iBAAiB,CAACb,aAAa,cAAAgB,qBAAA,uBAA/BA,qBAAA,CAAiCC,YAAY,CAAC,WAAW,CAAC,KAAI,EAAE,CAAC,EAAE;MAAA,IAAAD,qBAAA,EAAAE,kBAAA;MAC7HL,iBAAiB,GAAG,EAAAK,kBAAA,GAAAL,iBAAiB,cAAAK,kBAAA,uBAAjBA,kBAAA,CAAmBJ,UAAU,KAAI,IAAI;IAC3D;IACA,OAAOD,iBAAiB;EAC1B;EAEA,MAAMM,KAAkB,GAAG,CAACV,MAAM,CAAC;EACnC,IAAIW,IAAI,GAAG,EAAE;EACb,IAAIC,gBAAgB,GAAG,KAAK;EAC5B,MAAMC,QAAQ,GAAGb,MAAM,CAACc,UAAU,CAACd,MAAM,CAACc,UAAU,CAACvC,MAAM,GAAG,CAAC,CAAC;EAChE;EACA,IAAI,CAAAsC,QAAQ,aAARA,QAAQ,uBAARA,QAAQ,CAAEE,QAAQ,MAAK,KAAK,IAAI,CAACF,QAAQ,aAARA,QAAQ,uBAARA,QAAQ,CAAkBG,SAAS,MAAK,MAAM,EAAE;IACnFhB,MAAM,CAACL,WAAW,CAACkB,QAAQ,CAAC;EAC9B;EAEA,OAAOH,KAAK,CAACnC,MAAM,GAAG,CAAC,EAAE;IAAA,IAAA0C,mBAAA;IACvB,MAAMxC,IAAI,GAAGiC,KAAK,CAACQ,GAAG,CAAC,CAAC;IACxB,IAAI,CAACzC,IAAI,EAAE;MACT;IACF;;IAEA;IACA,MAAM0C,cAAc,GAAG,EAAAF,mBAAA,GAAAxC,IAAI,CAACc,aAAa,cAAA0B,mBAAA,uBAAlBA,mBAAA,CAAoBG,eAAe,MAAK,MAAM;IACrE,IAAID,cAAc,EAAE;MAClB;MACA;MACA,IAAI,CAACjB,SAAS,IAAIzB,IAAI,CAAC4C,QAAQ,KAAKC,IAAI,CAACC,SAAS,EAAE;QAClDX,gBAAgB,GAAG,KAAK;MAC1B,CAAC,MAAM;QAAA,IAAAY,qBAAA;QACL,MAAMC,UAAU,GAAGhD,IAAI,CAACgD,UAAyB;QACjD,MAAMC,yBAAyB,GAAG,CAAAD,UAAU,aAAVA,UAAU,gBAAAD,qBAAA,GAAVC,UAAU,CAAEjB,YAAY,cAAAgB,qBAAA,uBAAxBA,qBAAA,CAAAG,IAAA,CAAAF,UAAU,EAAiB,WAAW,CAAC,MAAK,OAAO,IAAIA,UAAU,CAACtC,WAAW,KAAK,EAAE;QACtH,IAAIyB,gBAAgB,IAAI,CAACc,yBAAyB,EAAE;UAClDf,IAAI,IAAI,IAAI;UACZC,gBAAgB,GAAG,KAAK;QAC1B;QACAA,gBAAgB,GAAG,IAAI;MACzB;IACF;IAEA,IAAInC,IAAI,CAAC4C,QAAQ,KAAKC,IAAI,CAACC,SAAS,EAAE;MACpC;MACAZ,IAAI,IAAIlC,IAAI,CAACU,WAAW;IAC1B,CAAC,MAAM,IAAIV,IAAI,CAACsC,QAAQ,KAAK,IAAI,EAAE;MAAA,IAAAa,qBAAA;MACjC,MAAMvB,UAAU,GAAGF,gBAAgB,CAAC1B,IAAI,CAAC;MACzC,IAAI4B,UAAU,IAAI,EAAAuB,qBAAA,GAAAvB,UAAU,CAACd,aAAa,cAAAqC,qBAAA,uBAAxBA,qBAAA,CAA0BR,eAAe,MAAK,MAAM,IAAI,CAAC,CAAE3C,IAAI,CAAiB+B,YAAY,CAAC,SAAS,CAAC,EAAE;QACzH;QACA;QACAG,IAAI,IAAI,IAAI;MACd;IACF,CAAC,MAAM;MACL,IAAIkB,CAAC,GAAGpD,IAAI,CAACqC,UAAU,CAACvC,MAAM,GAAG,CAAC;MAClC,OAAOsD,CAAC,GAAG,CAAC,CAAC,EAAE;QACb,MAAMC,KAAK,GAAGrD,IAAI,CAACqC,UAAU,CAACe,CAAC,CAAC;QAChC,IAAI,CAACC,KAAK,EAAE;UACV;QACF;QACApB,KAAK,CAACqB,IAAI,CAACD,KAAK,CAAC;QACjBD,CAAC,EAAE;MACL;IACF;EACF;EACAlB,IAAI,GAAGA,IAAI,CAACb,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC;;EAEpC;EACA,IAAIa,IAAI,KAAKX,MAAM,CAACH,KAAK,IAAIK,SAAS,aAATA,SAAS,eAATA,SAAS,CAAEI,QAAQ,CAAC,QAAQ,CAAC,EAAE;IAC1DK,IAAI,GAAGA,IAAI,CAACqB,KAAK,CAAC,CAAC,EAAE/B,cAAc,GAAG,CAAC,CAAC,GAAGU,IAAI,CAACqB,KAAK,CAAC/B,cAAc,CAAC;EACvE;EACA,OAAOU,IAAI;AACb;AAEA,SAAQ1C,gBAAgB,EAAEI,mBAAmB,EAAEG,gBAAgB,EAAEuB,oBAAoB,EAAEH,cAAc","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"inputUtils.d.ts","sourceRoot":"","sources":["../../../../../src/web/utils/inputUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,OAAO,CAAC;AACzC,OAAO,KAAK,EAAC,mBAAmB,EAAE,wBAAwB,EAAC,MAAM,6BAA6B,CAAC;AAM/F,iBAAS,gBAAgB,CAAC,WAAW,EAAE,UAAU,CAAC,aAAa,GAAG,mBAAmB,WAEpF;AAED,iBAAS,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,UAK3D;AAED,iBAAS,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,GAAG,SAAS,UAcvG;AAED,iBAAS,cAAc,CAAC,KAAK,EAAE,MAAM,UAEpC;AAGD,iBAAS,oBAAoB,CAAC,MAAM,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAuElH;AAED,OAAO,EAAC,gBAAgB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,cAAc,EAAC,CAAC"}
1
+ {"version":3,"file":"inputUtils.d.ts","sourceRoot":"","sources":["../../../../../src/web/utils/inputUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,OAAO,CAAC;AACzC,OAAO,KAAK,EAAC,mBAAmB,EAAE,wBAAwB,EAAC,MAAM,6BAA6B,CAAC;AAM/F,iBAAS,gBAAgB,CAAC,WAAW,EAAE,UAAU,CAAC,aAAa,GAAG,mBAAmB,WAEpF;AAED,iBAAS,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,UAK3D;AAED,iBAAS,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,GAAG,SAAS,UAcvG;AAED,iBAAS,cAAc,CAAC,KAAK,EAAE,MAAM,UAEpC;AAGD,iBAAS,oBAAoB,CAAC,MAAM,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAwElH;AAED,OAAO,EAAC,gBAAgB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,cAAc,EAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expensify/react-native-live-markdown",
3
- "version": "0.1.273",
3
+ "version": "0.1.275",
4
4
  "description": "Drop-in replacement for React Native's TextInput component with Markdown formatting.",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -65,8 +65,9 @@ function parseInnerHTMLToText(target: MarkdownTextInputElement, cursorPosition:
65
65
  // If we are operating on the nodes that are children of the MarkdownTextInputElement, we need to add a newline after each
66
66
  const isTopComponent = node.parentElement?.contentEditable === 'true';
67
67
  if (isTopComponent) {
68
- // Replaced text is beeing added as text node, so we need to not add the newline before and after it
69
- if (node.nodeType === Node.TEXT_NODE) {
68
+ // When inputType is undefined, the first part of the replaced text is added as a text node.
69
+ // Because of it, we need to prevent adding new lines in this case
70
+ if (!inputType && node.nodeType === Node.TEXT_NODE) {
70
71
  shouldAddNewline = false;
71
72
  } else {
72
73
  const firstChild = node.firstChild as HTMLElement;
@@ -1,14 +0,0 @@
1
- #import <React/RCTBackedTextInputDelegateAdapter.h>
2
- #import <RNLiveMarkdown/RCTMarkdownUtils.h>
3
-
4
- NS_ASSUME_NONNULL_BEGIN
5
-
6
- @interface RCTBackedTextFieldDelegateAdapter (Markdown)
7
-
8
- @property(nonatomic, nullable, getter=getMarkdownUtils) RCTMarkdownUtils *markdownUtils;
9
-
10
- - (void)markdown_textFieldDidChange;
11
-
12
- @end
13
-
14
- NS_ASSUME_NONNULL_END
@@ -1,43 +0,0 @@
1
- #import <RNLiveMarkdown/RCTBackedTextFieldDelegateAdapter+Markdown.h>
2
- #import <RNLiveMarkdown/RCTMarkdownUtils.h>
3
- #import <React/RCTUITextField.h>
4
- #import <objc/message.h>
5
-
6
- @implementation RCTBackedTextFieldDelegateAdapter (Markdown)
7
-
8
- - (void)setMarkdownUtils:(RCTMarkdownUtils *)markdownUtils {
9
- objc_setAssociatedObject(self, @selector(getMarkdownUtils), markdownUtils, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
10
- }
11
-
12
- - (RCTMarkdownUtils *)getMarkdownUtils {
13
- return objc_getAssociatedObject(self, @selector(getMarkdownUtils));
14
- }
15
-
16
- - (void)markdown_textFieldDidChange
17
- {
18
- RCTMarkdownUtils *markdownUtils = [self getMarkdownUtils];
19
- if (markdownUtils != nil) {
20
- RCTUITextField *backedTextInputView = [self valueForKey:@"_backedTextInputView"];
21
- UITextRange *range = backedTextInputView.selectedTextRange;
22
- backedTextInputView.attributedText = [markdownUtils parseMarkdown:backedTextInputView.attributedText withDefaultTextAttributes:backedTextInputView.defaultTextAttributes];
23
- [backedTextInputView setSelectedTextRange:range notifyDelegate:YES];
24
- }
25
-
26
- // Call the original method
27
- [self markdown_textFieldDidChange];
28
- }
29
-
30
- + (void)load
31
- {
32
- static dispatch_once_t onceToken;
33
- dispatch_once(&onceToken, ^{
34
- Class cls = [self class];
35
- SEL originalSelector = @selector(textFieldDidChange);
36
- SEL swizzledSelector = @selector(markdown_textFieldDidChange);
37
- Method originalMethod = class_getInstanceMethod(cls, originalSelector);
38
- Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector);
39
- method_exchangeImplementations(originalMethod, swizzledMethod);
40
- });
41
- }
42
-
43
- @end
@@ -1,19 +0,0 @@
1
- #import <UIKit/UIKit.h>
2
- #import <React/RCTUITextView.h>
3
- #import <RNLiveMarkdown/RCTMarkdownUtils.h>
4
-
5
- NS_ASSUME_NONNULL_BEGIN
6
-
7
- @interface RCTUITextView (Private)
8
- - (void)textDidChange;
9
- @end
10
-
11
- @interface RCTUITextView (Markdown)
12
-
13
- @property(nonatomic, nullable, getter=getMarkdownUtils) RCTMarkdownUtils *markdownUtils;
14
-
15
- - (void)markdown_textDidChange;
16
-
17
- @end
18
-
19
- NS_ASSUME_NONNULL_END
@@ -1,41 +0,0 @@
1
- #import <RNLiveMarkdown/RCTUITextView+Markdown.h>
2
- #import <RNLiveMarkdown/RCTMarkdownUtils.h>
3
- #import <objc/message.h>
4
-
5
- @implementation RCTUITextView (Markdown)
6
-
7
- - (void)setMarkdownUtils:(RCTMarkdownUtils *)markdownUtils {
8
- objc_setAssociatedObject(self, @selector(getMarkdownUtils), markdownUtils, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
9
- }
10
-
11
- - (RCTMarkdownUtils *)getMarkdownUtils {
12
- return objc_getAssociatedObject(self, @selector(getMarkdownUtils));
13
- }
14
-
15
- - (void)markdown_textDidChange
16
- {
17
- RCTMarkdownUtils *markdownUtils = [self getMarkdownUtils];
18
- if (markdownUtils != nil) {
19
- UITextRange *range = self.selectedTextRange;
20
- super.attributedText = [markdownUtils parseMarkdown:self.attributedText withDefaultTextAttributes:self.defaultTextAttributes];
21
- [super setSelectedTextRange:range]; // prevents cursor from jumping at the end when typing in the middle of the text
22
- }
23
-
24
- // Call the original method
25
- [self markdown_textDidChange];
26
- }
27
-
28
- + (void)load
29
- {
30
- static dispatch_once_t onceToken;
31
- dispatch_once(&onceToken, ^{
32
- Class cls = [self class];
33
- SEL originalSelector = @selector(textDidChange);
34
- SEL swizzledSelector = @selector(markdown_textDidChange);
35
- Method originalMethod = class_getInstanceMethod(cls, originalSelector);
36
- Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector);
37
- method_exchangeImplementations(originalMethod, swizzledMethod);
38
- });
39
- }
40
-
41
- @end