@expensify/react-native-live-markdown 0.1.294 → 0.1.296

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.
@@ -0,0 +1,15 @@
1
+ #import <RNLiveMarkdown/RCTMarkdownUtils.h>
2
+ #import <UIKit/UIKit.h>
3
+
4
+ NS_ASSUME_NONNULL_BEGIN
5
+
6
+ API_AVAILABLE(ios(15.0))
7
+ @interface BlockquoteTextLayoutFragment : NSTextLayoutFragment
8
+
9
+ @property (nonnull, atomic) RCTMarkdownUtils *markdownUtils;
10
+
11
+ @property NSUInteger depth;
12
+
13
+ @end
14
+
15
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,51 @@
1
+ #import <RNLiveMarkdown/BlockquoteTextLayoutFragment.h>
2
+
3
+ @implementation BlockquoteTextLayoutFragment
4
+
5
+ - (CGRect)boundingRect {
6
+ CGRect fragmentTextBounds = CGRectNull;
7
+ for (NSTextLineFragment *lineFragment in self.textLineFragments) {
8
+ if (lineFragment.characterRange.length == 0) {
9
+ continue;
10
+ }
11
+ CGRect lineFragmentBounds = lineFragment.typographicBounds;
12
+ if (CGRectIsNull(fragmentTextBounds)) {
13
+ fragmentTextBounds = lineFragmentBounds;
14
+ } else {
15
+ fragmentTextBounds = CGRectUnion(fragmentTextBounds, lineFragmentBounds);
16
+ }
17
+ }
18
+
19
+ CGFloat marginLeft = _markdownUtils.markdownStyle.blockquoteMarginLeft;
20
+ CGFloat borderWidth = _markdownUtils.markdownStyle.blockquoteBorderWidth;
21
+ CGFloat paddingLeft = _markdownUtils.markdownStyle.blockquotePaddingLeft;
22
+ CGFloat shift = marginLeft + borderWidth + paddingLeft;
23
+
24
+ fragmentTextBounds.origin.x -= (paddingLeft + borderWidth) + shift * (_depth - 1);
25
+ fragmentTextBounds.size.width = borderWidth + shift * (_depth - 1);
26
+
27
+ return fragmentTextBounds;
28
+ }
29
+
30
+ - (void)drawAtPoint:(CGPoint)point inContext:(CGContextRef)ctx {
31
+ CGFloat marginLeft = _markdownUtils.markdownStyle.blockquoteMarginLeft;
32
+ CGFloat borderWidth = _markdownUtils.markdownStyle.blockquoteBorderWidth;
33
+ CGFloat paddingLeft = _markdownUtils.markdownStyle.blockquotePaddingLeft;
34
+ CGFloat shift = marginLeft + borderWidth + paddingLeft;
35
+
36
+ [_markdownUtils.markdownStyle.blockquoteBorderColor setFill];
37
+
38
+ CGRect boundingRect = self.boundingRect;
39
+ for (NSUInteger i = 0; i < _depth; ++i) {
40
+ CGRect ribbonRect = CGRectMake(boundingRect.origin.x + i * shift, boundingRect.origin.y, borderWidth, boundingRect.size.height);
41
+ UIRectFill(ribbonRect);
42
+ }
43
+
44
+ [super drawAtPoint:point inContext:ctx];
45
+ }
46
+
47
+ - (CGRect)renderingSurfaceBounds {
48
+ return CGRectUnion(self.boundingRect, [super renderingSurfaceBounds]);
49
+ }
50
+
51
+ @end
@@ -3,13 +3,13 @@
3
3
  @implementation MarkdownRange
4
4
 
5
5
  - (instancetype)initWithType:(NSString *)type range:(NSRange)range depth:(NSUInteger)depth {
6
- self = [super init];
7
- if (self) {
8
- _type = type;
9
- _range = range;
10
- _depth = depth;
11
- }
12
- return self;
6
+ self = [super init];
7
+ if (self) {
8
+ _type = type;
9
+ _range = range;
10
+ _depth = depth;
11
+ }
12
+ return self;
13
13
  }
14
14
 
15
15
  @end
@@ -7,6 +7,7 @@
7
7
 
8
8
  #import <RNLiveMarkdown/MarkdownBackedTextInputDelegate.h>
9
9
  #import <RNLiveMarkdown/MarkdownLayoutManager.h>
10
+ #import <RNLiveMarkdown/MarkdownTextLayoutManagerDelegate.h>
10
11
  #import <RNLiveMarkdown/MarkdownTextFieldObserver.h>
11
12
  #import <RNLiveMarkdown/MarkdownTextViewObserver.h>
12
13
  #import <RNLiveMarkdown/MarkdownTextInputDecoratorComponentView.h>
@@ -22,6 +23,7 @@ using namespace facebook::react;
22
23
  RCTMarkdownUtils *_markdownUtils;
23
24
  RCTMarkdownStyle *_markdownStyle;
24
25
  NSNumber *_parserId;
26
+ MarkdownTextLayoutManagerDelegate *_markdownTextLayoutManagerDelegate;
25
27
  MarkdownBackedTextInputDelegate *_markdownBackedTextInputDelegate;
26
28
  MarkdownTextStorageDelegate *_markdownTextStorageDelegate;
27
29
  MarkdownTextViewObserver *_markdownTextViewObserver;
@@ -111,18 +113,25 @@ using namespace facebook::react;
111
113
  // format initial value
112
114
  [_textView.textStorage setAttributedString:_textView.attributedText];
113
115
 
114
- NSLayoutManager *layoutManager = _textView.layoutManager; // switching to TextKit 1 compatibility mode
115
-
116
- // Correct content height in TextKit 1 compatibility mode. (See https://github.com/Expensify/App/issues/41567)
117
- // Consider removing this fix if it is no longer needed after migrating to TextKit 2.
118
- CGSize contentSize = _textView.contentSize;
119
- CGRect textBounds = [layoutManager usedRectForTextContainer:_textView.textContainer];
120
- contentSize.height = textBounds.size.height + _textView.textContainerInset.top + _textView.textContainerInset.bottom;
121
- [_textView setContentSize:contentSize];
122
-
123
- layoutManager.allowsNonContiguousLayout = NO; // workaround for onScroll issue
124
- object_setClass(layoutManager, [MarkdownLayoutManager class]);
125
- [layoutManager setValue:_markdownUtils forKey:@"markdownUtils"];
116
+ if (@available(iOS 16.0, *)) {
117
+ _markdownTextLayoutManagerDelegate = [[MarkdownTextLayoutManagerDelegate alloc] init];
118
+ _markdownTextLayoutManagerDelegate.textStorage = _textView.textStorage;
119
+ _markdownTextLayoutManagerDelegate.markdownUtils = _markdownUtils;
120
+ _textView.textLayoutManager.delegate = _markdownTextLayoutManagerDelegate;
121
+ } else {
122
+ NSLayoutManager *layoutManager = _textView.layoutManager; // switching to TextKit 1 compatibility mode
123
+
124
+ // Correct content height in TextKit 1 compatibility mode. (See https://github.com/Expensify/App/issues/41567)
125
+ // Consider removing this fix if it is no longer needed after migrating to TextKit 2.
126
+ CGSize contentSize = _textView.contentSize;
127
+ CGRect textBounds = [layoutManager usedRectForTextContainer:_textView.textContainer];
128
+ contentSize.height = textBounds.size.height + _textView.textContainerInset.top + _textView.textContainerInset.bottom;
129
+ [_textView setContentSize:contentSize];
130
+
131
+ layoutManager.allowsNonContiguousLayout = NO; // workaround for onScroll issue
132
+ object_setClass(layoutManager, [MarkdownLayoutManager class]);
133
+ [layoutManager setValue:_markdownUtils forKey:@"markdownUtils"];
134
+ }
126
135
 
127
136
  // register delegate for fixing cursor position after blockquote
128
137
  _markdownBackedTextInputDelegate = [[MarkdownBackedTextInputDelegate alloc] initWithTextView:_textView];
@@ -137,7 +146,9 @@ using namespace facebook::react;
137
146
  _observersAdded = false;
138
147
 
139
148
  if (_textView != nil) {
140
- if (_textView.layoutManager != nil && [object_getClass(_textView.layoutManager) isEqual:[MarkdownLayoutManager class]]) {
149
+ if (@available(iOS 16.0, *)) {
150
+ _textView.textLayoutManager.delegate = nil;
151
+ } else if (_textView.layoutManager != nil && [object_getClass(_textView.layoutManager) isEqual:[MarkdownLayoutManager class]]) {
141
152
  [_textView.layoutManager setValue:nil forKey:@"markdownUtils"];
142
153
  object_setClass(_textView.layoutManager, [NSLayoutManager class]);
143
154
  }
@@ -0,0 +1,14 @@
1
+ #import <RNLiveMarkdown/RCTMarkdownUtils.h>
2
+ #import <UIKit/UIKit.h>
3
+
4
+ NS_ASSUME_NONNULL_BEGIN
5
+
6
+ @interface MarkdownTextLayoutManagerDelegate : NSObject <NSTextLayoutManagerDelegate>
7
+
8
+ @property (nonnull, atomic) NSTextStorage *textStorage;
9
+
10
+ @property (nonnull, atomic) RCTMarkdownUtils *markdownUtils;
11
+
12
+ @end
13
+
14
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,22 @@
1
+ #import <RNLiveMarkdown/MarkdownTextLayoutManagerDelegate.h>
2
+ #import <RNLiveMarkdown/BlockquoteTextLayoutFragment.h>
3
+ #import <RNLiveMarkdown/MarkdownFormatter.h>
4
+
5
+ @implementation MarkdownTextLayoutManagerDelegate
6
+
7
+ - (NSTextLayoutFragment *)textLayoutManager:(NSTextLayoutManager *)textLayoutManager textLayoutFragmentForLocation:(id <NSTextLocation>)location inTextElement:(NSTextElement *)textElement
8
+ API_AVAILABLE(ios(15.0)){
9
+ NSInteger index = [textLayoutManager offsetFromLocation:textLayoutManager.documentRange.location toLocation:location];
10
+ if (index < self.textStorage.length) {
11
+ NSNumber *depth = [self.textStorage attribute:RCTLiveMarkdownBlockquoteDepthAttributeName atIndex:index effectiveRange:nil];
12
+ if (depth != nil) {
13
+ BlockquoteTextLayoutFragment *textLayoutFragment = [[BlockquoteTextLayoutFragment alloc] initWithTextElement:textElement range:textElement.elementRange];
14
+ textLayoutFragment.markdownUtils = _markdownUtils;
15
+ textLayoutFragment.depth = [depth unsignedIntValue];
16
+ return textLayoutFragment;
17
+ }
18
+ }
19
+ return [[NSTextLayoutFragment alloc] initWithTextElement:textElement range:textElement.elementRange];
20
+ }
21
+
22
+ @end
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expensify/react-native-live-markdown",
3
- "version": "0.1.294",
3
+ "version": "0.1.296",
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",