react-native-enriched 0.2.0 → 0.2.1
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 +1 -5
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +3 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +1 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.cpp +10 -0
- package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h +7 -0
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +92 -0
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/events/MentionHandler.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/events/OnRequestHtmlResultEvent.kt +33 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedCodeBlockSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedImageSpan.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedOrderedListSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +9 -3
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +5 -0
- package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnorderedListSpan.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/styles/HtmlStyle.kt +78 -0
- package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +80 -4
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +8 -0
- package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.cpp +6 -6
- package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.h +6 -6
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputComponentDescriptor.h +19 -19
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.cpp +40 -51
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.h +13 -15
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.cpp +23 -21
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.h +35 -36
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.cpp +4 -4
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.h +13 -14
- package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/conversions.h +12 -13
- package/ios/EnrichedTextInputView.h +25 -13
- package/ios/EnrichedTextInputView.mm +872 -581
- package/ios/attachments/ImageAttachment.h +10 -0
- package/ios/attachments/ImageAttachment.mm +34 -0
- package/ios/attachments/MediaAttachment.h +23 -0
- package/ios/attachments/MediaAttachment.mm +31 -0
- package/ios/config/InputConfig.h +6 -6
- package/ios/config/InputConfig.mm +39 -33
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +10 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +7 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +21 -0
- package/ios/inputParser/InputParser.h +5 -5
- package/ios/inputParser/InputParser.mm +789 -378
- package/ios/inputTextView/InputTextView.h +1 -1
- package/ios/inputTextView/InputTextView.mm +100 -59
- package/ios/internals/EnrichedTextInputViewComponentDescriptor.h +11 -9
- package/ios/internals/EnrichedTextInputViewShadowNode.h +28 -25
- package/ios/internals/EnrichedTextInputViewShadowNode.mm +45 -40
- package/ios/internals/EnrichedTextInputViewState.h +3 -1
- package/ios/styles/BlockQuoteStyle.mm +189 -118
- package/ios/styles/BoldStyle.mm +95 -63
- package/ios/styles/CodeBlockStyle.mm +204 -128
- package/ios/styles/H1Style.mm +10 -4
- package/ios/styles/H2Style.mm +10 -4
- package/ios/styles/H3Style.mm +10 -4
- package/ios/styles/HeadingStyleBase.mm +129 -84
- package/ios/styles/ImageStyle.mm +75 -73
- package/ios/styles/InlineCodeStyle.mm +148 -85
- package/ios/styles/ItalicStyle.mm +76 -52
- package/ios/styles/LinkStyle.mm +348 -227
- package/ios/styles/MentionStyle.mm +363 -246
- package/ios/styles/OrderedListStyle.mm +171 -106
- package/ios/styles/StrikethroughStyle.mm +52 -35
- package/ios/styles/UnderlineStyle.mm +68 -46
- package/ios/styles/UnorderedListStyle.mm +169 -106
- package/ios/utils/BaseStyleProtocol.h +2 -2
- package/ios/utils/ColorExtension.mm +7 -5
- package/ios/utils/FontExtension.mm +42 -27
- package/ios/utils/LayoutManagerExtension.h +1 -1
- package/ios/utils/LayoutManagerExtension.mm +280 -170
- package/ios/utils/MentionParams.h +0 -1
- package/ios/utils/MentionStyleProps.h +1 -1
- package/ios/utils/MentionStyleProps.mm +27 -20
- package/ios/utils/OccurenceUtils.h +42 -42
- package/ios/utils/OccurenceUtils.mm +142 -119
- package/ios/utils/ParagraphAttributesUtils.h +6 -2
- package/ios/utils/ParagraphAttributesUtils.mm +115 -71
- package/ios/utils/ParagraphsUtils.h +2 -1
- package/ios/utils/ParagraphsUtils.mm +40 -26
- package/ios/utils/StringExtension.h +1 -1
- package/ios/utils/StringExtension.mm +19 -16
- package/ios/utils/StyleHeaders.h +27 -15
- package/ios/utils/TextInsertionUtils.h +13 -2
- package/ios/utils/TextInsertionUtils.mm +38 -20
- package/ios/utils/WordsUtils.h +2 -1
- package/ios/utils/WordsUtils.mm +32 -22
- package/ios/utils/ZeroWidthSpaceUtils.h +3 -1
- package/ios/utils/ZeroWidthSpaceUtils.mm +145 -79
- package/lib/module/EnrichedTextInput.js +39 -1
- package/lib/module/EnrichedTextInput.js.map +1 -1
- package/lib/module/EnrichedTextInputNativeComponent.ts +11 -0
- package/lib/typescript/src/EnrichedTextInput.d.ts +1 -0
- package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +6 -0
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -1
- package/package.json +8 -1
- package/src/EnrichedTextInput.tsx +45 -0
- package/src/EnrichedTextInputNativeComponent.ts +11 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#import "LayoutManagerExtension.h"
|
|
2
|
-
#import
|
|
2
|
+
#import "ColorExtension.h"
|
|
3
3
|
#import "EnrichedTextInputView.h"
|
|
4
|
-
#import "StyleHeaders.h"
|
|
5
4
|
#import "ParagraphsUtils.h"
|
|
6
|
-
#import "
|
|
5
|
+
#import "StyleHeaders.h"
|
|
6
|
+
#import <objc/runtime.h>
|
|
7
7
|
|
|
8
8
|
@implementation NSLayoutManager (LayoutManagerExtension)
|
|
9
9
|
|
|
@@ -14,12 +14,8 @@ static void const *kInputKey = &kInputKey;
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
- (void)setInput:(id)value {
|
|
17
|
-
objc_setAssociatedObject(
|
|
18
|
-
|
|
19
|
-
kInputKey,
|
|
20
|
-
value,
|
|
21
|
-
OBJC_ASSOCIATION_RETAIN_NONATOMIC
|
|
22
|
-
);
|
|
17
|
+
objc_setAssociatedObject(self, kInputKey, value,
|
|
18
|
+
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
23
19
|
}
|
|
24
20
|
|
|
25
21
|
+ (void)load {
|
|
@@ -30,104 +26,145 @@ static void const *kInputKey = &kInputKey;
|
|
|
30
26
|
SEL swizzledSelector = @selector(my_drawBackgroundForGlyphRange:atPoint:);
|
|
31
27
|
Method originalMethod = class_getInstanceMethod(myClass, originalSelector);
|
|
32
28
|
Method swizzledMethod = class_getInstanceMethod(myClass, swizzledSelector);
|
|
33
|
-
|
|
34
|
-
BOOL didAddMethod = class_addMethod(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if(didAddMethod) {
|
|
29
|
+
|
|
30
|
+
BOOL didAddMethod = class_addMethod(
|
|
31
|
+
myClass, originalSelector, method_getImplementation(swizzledMethod),
|
|
32
|
+
method_getTypeEncoding(swizzledMethod));
|
|
33
|
+
|
|
34
|
+
if (didAddMethod) {
|
|
40
35
|
class_replaceMethod(myClass, swizzledSelector,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
);
|
|
36
|
+
method_getImplementation(originalMethod),
|
|
37
|
+
method_getTypeEncoding(originalMethod));
|
|
44
38
|
} else {
|
|
45
39
|
method_exchangeImplementations(originalMethod, swizzledMethod);
|
|
46
40
|
}
|
|
47
41
|
});
|
|
48
42
|
}
|
|
49
43
|
|
|
50
|
-
- (void)my_drawBackgroundForGlyphRange:(NSRange)glyphRange
|
|
44
|
+
- (void)my_drawBackgroundForGlyphRange:(NSRange)glyphRange
|
|
45
|
+
atPoint:(CGPoint)origin {
|
|
51
46
|
[self my_drawBackgroundForGlyphRange:glyphRange atPoint:origin];
|
|
52
|
-
|
|
47
|
+
|
|
53
48
|
EnrichedTextInputView *typedInput = (EnrichedTextInputView *)self.input;
|
|
54
|
-
if(typedInput == nullptr) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
[self
|
|
59
|
-
|
|
60
|
-
|
|
49
|
+
if (typedInput == nullptr) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
NSRange visibleCharRange = [self characterRangeForGlyphRange:glyphRange
|
|
54
|
+
actualGlyphRange:NULL];
|
|
55
|
+
|
|
56
|
+
[self drawBlockQuotes:typedInput
|
|
57
|
+
origin:origin
|
|
58
|
+
visibleCharRange:visibleCharRange];
|
|
59
|
+
[self drawLists:typedInput origin:origin visibleCharRange:visibleCharRange];
|
|
60
|
+
[self drawCodeBlocks:typedInput
|
|
61
|
+
origin:origin
|
|
62
|
+
visibleCharRange:visibleCharRange];
|
|
61
63
|
}
|
|
62
64
|
|
|
63
|
-
- (void)drawCodeBlocks:(EnrichedTextInputView *)typedInput
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
65
|
+
- (void)drawCodeBlocks:(EnrichedTextInputView *)typedInput
|
|
66
|
+
origin:(CGPoint)origin
|
|
67
|
+
visibleCharRange:(NSRange)visibleCharRange {
|
|
68
|
+
CodeBlockStyle *codeBlockStyle =
|
|
69
|
+
typedInput->stylesDict[@([CodeBlockStyle getStyleType])];
|
|
70
|
+
if (codeBlockStyle == nullptr) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
NSArray<StylePair *> *allCodeBlocks =
|
|
75
|
+
[codeBlockStyle findAllOccurences:visibleCharRange];
|
|
76
|
+
NSArray<StylePair *> *mergedCodeBlocks =
|
|
77
|
+
[self mergeContiguousStylePairs:allCodeBlocks];
|
|
78
|
+
UIColor *bgColor = [[typedInput->config codeBlockBgColor]
|
|
79
|
+
colorWithAlphaIfNotTransparent:0.4];
|
|
71
80
|
CGFloat radius = [typedInput->config codeBlockBorderRadius];
|
|
72
81
|
[bgColor setFill];
|
|
73
|
-
|
|
82
|
+
|
|
74
83
|
for (StylePair *pair in mergedCodeBlocks) {
|
|
75
84
|
NSRange blockCharacterRange = [pair.rangeValue rangeValue];
|
|
76
|
-
if (blockCharacterRange.length == 0)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
if (blockCharacterRange.length == 0)
|
|
86
|
+
continue;
|
|
87
|
+
|
|
88
|
+
NSArray *paragraphs =
|
|
89
|
+
[ParagraphsUtils getSeparateParagraphsRangesIn:typedInput->textView
|
|
90
|
+
range:blockCharacterRange];
|
|
91
|
+
if (paragraphs.count == 0)
|
|
92
|
+
continue;
|
|
93
|
+
|
|
94
|
+
NSRange firstParagraphRange =
|
|
95
|
+
[((NSValue *)[paragraphs firstObject]) rangeValue];
|
|
96
|
+
NSRange lastParagraphRange =
|
|
97
|
+
[((NSValue *)[paragraphs lastObject]) rangeValue];
|
|
83
98
|
|
|
84
99
|
for (NSValue *paragraphValue in paragraphs) {
|
|
85
100
|
NSRange paragraphCharacterRange = [paragraphValue rangeValue];
|
|
86
|
-
|
|
87
|
-
BOOL isFirstParagraph =
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
101
|
+
|
|
102
|
+
BOOL isFirstParagraph =
|
|
103
|
+
NSEqualRanges(paragraphCharacterRange, firstParagraphRange);
|
|
104
|
+
BOOL isLastParagraph =
|
|
105
|
+
NSEqualRanges(paragraphCharacterRange, lastParagraphRange);
|
|
106
|
+
|
|
107
|
+
NSRange paragraphGlyphRange =
|
|
108
|
+
[self glyphRangeForCharacterRange:paragraphCharacterRange
|
|
109
|
+
actualCharacterRange:NULL];
|
|
110
|
+
|
|
92
111
|
__block BOOL isFirstLineOfParagraph = YES;
|
|
93
|
-
|
|
94
|
-
[self
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
112
|
+
|
|
113
|
+
[self
|
|
114
|
+
enumerateLineFragmentsForGlyphRange:paragraphGlyphRange
|
|
115
|
+
usingBlock:^(
|
|
116
|
+
CGRect rect, CGRect usedRect,
|
|
117
|
+
NSTextContainer *_Nonnull textContainer,
|
|
118
|
+
NSRange glyphRange,
|
|
119
|
+
BOOL *_Nonnull stop) {
|
|
120
|
+
CGRect lineBgRect = rect;
|
|
121
|
+
lineBgRect.origin.x = origin.x;
|
|
122
|
+
lineBgRect.origin.y += origin.y;
|
|
123
|
+
lineBgRect.size.width =
|
|
124
|
+
textContainer.size.width;
|
|
125
|
+
|
|
126
|
+
UIRectCorner cornersForThisLine = 0;
|
|
127
|
+
|
|
128
|
+
if (isFirstParagraph &&
|
|
129
|
+
isFirstLineOfParagraph) {
|
|
130
|
+
cornersForThisLine =
|
|
131
|
+
UIRectCornerTopLeft |
|
|
132
|
+
UIRectCornerTopRight;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
BOOL isLastLineOfParagraph =
|
|
136
|
+
(NSMaxRange(glyphRange) >=
|
|
137
|
+
NSMaxRange(paragraphGlyphRange));
|
|
138
|
+
|
|
139
|
+
if (isLastParagraph &&
|
|
140
|
+
isLastLineOfParagraph) {
|
|
141
|
+
cornersForThisLine =
|
|
142
|
+
cornersForThisLine |
|
|
143
|
+
UIRectCornerBottomLeft |
|
|
144
|
+
UIRectCornerBottomRight;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
UIBezierPath *path = [UIBezierPath
|
|
148
|
+
bezierPathWithRoundedRect:lineBgRect
|
|
149
|
+
byRoundingCorners:
|
|
150
|
+
cornersForThisLine
|
|
151
|
+
cornerRadii:CGSizeMake(
|
|
152
|
+
radius,
|
|
153
|
+
radius)];
|
|
154
|
+
[path fill];
|
|
155
|
+
|
|
156
|
+
isFirstLineOfParagraph = NO;
|
|
157
|
+
}];
|
|
121
158
|
}
|
|
122
159
|
}
|
|
123
160
|
}
|
|
124
161
|
|
|
125
|
-
- (NSArray<StylePair *> *)mergeContiguousStylePairs:
|
|
126
|
-
{
|
|
162
|
+
- (NSArray<StylePair *> *)mergeContiguousStylePairs:
|
|
163
|
+
(NSArray<StylePair *> *)pairs {
|
|
127
164
|
if (pairs.count == 0) {
|
|
128
165
|
return @[];
|
|
129
166
|
}
|
|
130
|
-
|
|
167
|
+
|
|
131
168
|
NSMutableArray<StylePair *> *mergedPairs = [[NSMutableArray alloc] init];
|
|
132
169
|
StylePair *currentPair = pairs[0];
|
|
133
170
|
NSRange currentRange = [currentPair.rangeValue rangeValue];
|
|
@@ -148,7 +185,7 @@ static void const *kInputKey = &kInputKey;
|
|
|
148
185
|
mergedPair.rangeValue = [NSValue valueWithRange:currentRange];
|
|
149
186
|
mergedPair.styleValue = currentPair.styleValue;
|
|
150
187
|
[mergedPairs addObject:mergedPair];
|
|
151
|
-
|
|
188
|
+
|
|
152
189
|
// 2. Start a brand new block.
|
|
153
190
|
currentPair = nextPair;
|
|
154
191
|
currentRange = nextRange;
|
|
@@ -164,108 +201,181 @@ static void const *kInputKey = &kInputKey;
|
|
|
164
201
|
return mergedPairs;
|
|
165
202
|
}
|
|
166
203
|
|
|
167
|
-
- (void)drawBlockQuotes:(EnrichedTextInputView *)typedInput
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
204
|
+
- (void)drawBlockQuotes:(EnrichedTextInputView *)typedInput
|
|
205
|
+
origin:(CGPoint)origin
|
|
206
|
+
visibleCharRange:(NSRange)visibleCharRange {
|
|
207
|
+
BlockQuoteStyle *bqStyle =
|
|
208
|
+
typedInput->stylesDict[@([BlockQuoteStyle getStyleType])];
|
|
209
|
+
if (bqStyle == nullptr) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
NSArray *allBlockquotes = [bqStyle findAllOccurences:visibleCharRange];
|
|
214
|
+
|
|
215
|
+
for (StylePair *pair in allBlockquotes) {
|
|
216
|
+
NSRange paragraphRange = [typedInput->textView.textStorage.string
|
|
217
|
+
paragraphRangeForRange:[pair.rangeValue rangeValue]];
|
|
218
|
+
NSRange paragraphGlyphRange =
|
|
219
|
+
[self glyphRangeForCharacterRange:paragraphRange
|
|
220
|
+
actualCharacterRange:nullptr];
|
|
221
|
+
[self
|
|
222
|
+
enumerateLineFragmentsForGlyphRange:paragraphGlyphRange
|
|
223
|
+
usingBlock:^(
|
|
224
|
+
CGRect rect, CGRect usedRect,
|
|
225
|
+
NSTextContainer *_Nonnull textContainer,
|
|
226
|
+
NSRange glyphRange, BOOL *_Nonnull stop) {
|
|
227
|
+
CGFloat paddingLeft = origin.x;
|
|
228
|
+
CGFloat paddingTop = origin.y;
|
|
229
|
+
CGFloat x = paddingLeft;
|
|
230
|
+
CGFloat y = paddingTop + rect.origin.y;
|
|
231
|
+
CGFloat width =
|
|
232
|
+
[typedInput
|
|
233
|
+
->config blockquoteBorderWidth];
|
|
234
|
+
CGFloat height = rect.size.height;
|
|
235
|
+
|
|
236
|
+
CGRect lineRect =
|
|
237
|
+
CGRectMake(x, y, width, height);
|
|
238
|
+
[[typedInput->config blockquoteBorderColor]
|
|
239
|
+
setFill];
|
|
240
|
+
UIRectFill(lineRect);
|
|
241
|
+
}];
|
|
192
242
|
}
|
|
193
243
|
}
|
|
194
244
|
|
|
195
|
-
- (void)drawLists:(EnrichedTextInputView *)typedInput
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
245
|
+
- (void)drawLists:(EnrichedTextInputView *)typedInput
|
|
246
|
+
origin:(CGPoint)origin
|
|
247
|
+
visibleCharRange:(NSRange)visibleCharRange {
|
|
248
|
+
UnorderedListStyle *ulStyle =
|
|
249
|
+
typedInput->stylesDict[@([UnorderedListStyle getStyleType])];
|
|
250
|
+
OrderedListStyle *olStyle =
|
|
251
|
+
typedInput->stylesDict[@([OrderedListStyle getStyleType])];
|
|
252
|
+
if (ulStyle == nullptr || olStyle == nullptr) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
202
256
|
NSMutableArray *allLists = [[NSMutableArray alloc] init];
|
|
203
|
-
[allLists addObjectsFromArray:[ulStyle findAllOccurences:
|
|
204
|
-
[allLists addObjectsFromArray:[olStyle findAllOccurences:
|
|
205
|
-
|
|
206
|
-
for(StylePair *pair in allLists) {
|
|
257
|
+
[allLists addObjectsFromArray:[ulStyle findAllOccurences:visibleCharRange]];
|
|
258
|
+
[allLists addObjectsFromArray:[olStyle findAllOccurences:visibleCharRange]];
|
|
259
|
+
|
|
260
|
+
for (StylePair *pair in allLists) {
|
|
207
261
|
NSParagraphStyle *pStyle = (NSParagraphStyle *)pair.styleValue;
|
|
208
262
|
NSDictionary *markerAttributes = @{
|
|
209
|
-
NSFontAttributeName: [typedInput->config orderedListMarkerFont],
|
|
210
|
-
NSForegroundColorAttributeName:
|
|
263
|
+
NSFontAttributeName : [typedInput->config orderedListMarkerFont],
|
|
264
|
+
NSForegroundColorAttributeName :
|
|
265
|
+
[typedInput->config orderedListMarkerColor]
|
|
211
266
|
};
|
|
212
|
-
|
|
213
|
-
NSArray *paragraphs = [ParagraphsUtils
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
267
|
+
|
|
268
|
+
NSArray *paragraphs = [ParagraphsUtils
|
|
269
|
+
getSeparateParagraphsRangesIn:typedInput->textView
|
|
270
|
+
range:[pair.rangeValue rangeValue]];
|
|
271
|
+
|
|
272
|
+
for (NSValue *paragraph in paragraphs) {
|
|
273
|
+
NSRange paragraphGlyphRange =
|
|
274
|
+
[self glyphRangeForCharacterRange:[paragraph rangeValue]
|
|
275
|
+
actualCharacterRange:nullptr];
|
|
276
|
+
|
|
277
|
+
[self
|
|
278
|
+
enumerateLineFragmentsForGlyphRange:paragraphGlyphRange
|
|
279
|
+
usingBlock:^(CGRect rect, CGRect usedRect,
|
|
280
|
+
NSTextContainer *container,
|
|
281
|
+
NSRange lineGlyphRange,
|
|
282
|
+
BOOL *stop) {
|
|
283
|
+
NSString *marker = [self
|
|
284
|
+
markerForList:pStyle.textLists
|
|
285
|
+
.firstObject
|
|
286
|
+
charIndex:
|
|
287
|
+
[self
|
|
288
|
+
characterIndexForGlyphAtIndex:
|
|
289
|
+
lineGlyphRange
|
|
290
|
+
.location]
|
|
291
|
+
input:typedInput];
|
|
292
|
+
|
|
293
|
+
if (pStyle.textLists.firstObject
|
|
294
|
+
.markerFormat ==
|
|
295
|
+
NSTextListMarkerDecimal) {
|
|
296
|
+
CGFloat gapWidth =
|
|
297
|
+
[typedInput->config
|
|
298
|
+
orderedListGapWidth];
|
|
299
|
+
CGFloat markerWidth =
|
|
300
|
+
[marker sizeWithAttributes:
|
|
301
|
+
markerAttributes]
|
|
302
|
+
.width;
|
|
303
|
+
CGFloat markerX = usedRect.origin.x -
|
|
304
|
+
gapWidth -
|
|
305
|
+
markerWidth / 2;
|
|
306
|
+
|
|
307
|
+
[marker drawAtPoint:CGPointMake(
|
|
308
|
+
markerX,
|
|
309
|
+
usedRect.origin
|
|
310
|
+
.y +
|
|
311
|
+
origin.y)
|
|
312
|
+
withAttributes:markerAttributes];
|
|
313
|
+
} else {
|
|
314
|
+
CGFloat gapWidth =
|
|
315
|
+
[typedInput->config
|
|
316
|
+
unorderedListGapWidth];
|
|
317
|
+
CGFloat bulletSize =
|
|
318
|
+
[typedInput->config
|
|
319
|
+
unorderedListBulletSize];
|
|
320
|
+
CGFloat bulletX = usedRect.origin.x -
|
|
321
|
+
gapWidth -
|
|
322
|
+
bulletSize / 2;
|
|
323
|
+
CGFloat centerY =
|
|
324
|
+
CGRectGetMidY(usedRect);
|
|
325
|
+
|
|
326
|
+
CGContextRef context =
|
|
327
|
+
UIGraphicsGetCurrentContext();
|
|
328
|
+
CGContextSaveGState(context);
|
|
329
|
+
{
|
|
330
|
+
[[typedInput->config
|
|
331
|
+
unorderedListBulletColor]
|
|
332
|
+
setFill];
|
|
333
|
+
CGContextAddArc(
|
|
334
|
+
context, bulletX, centerY,
|
|
335
|
+
bulletSize / 2, 0, 2 * M_PI, YES);
|
|
336
|
+
CGContextFillPath(context);
|
|
337
|
+
}
|
|
338
|
+
CGContextRestoreGState(context);
|
|
339
|
+
}
|
|
340
|
+
// only first line of a list gets its
|
|
341
|
+
// marker drawn
|
|
342
|
+
*stop = YES;
|
|
343
|
+
}];
|
|
246
344
|
}
|
|
247
345
|
}
|
|
248
346
|
}
|
|
249
347
|
|
|
250
|
-
- (NSString *)markerForList:(NSTextList *)list
|
|
251
|
-
|
|
348
|
+
- (NSString *)markerForList:(NSTextList *)list
|
|
349
|
+
charIndex:(NSUInteger)index
|
|
350
|
+
input:(EnrichedTextInputView *)input {
|
|
351
|
+
if (list.markerFormat == NSTextListMarkerDecimal) {
|
|
252
352
|
NSString *fullText = input->textView.textStorage.string;
|
|
253
353
|
NSInteger itemNumber = 1;
|
|
254
|
-
|
|
255
|
-
NSRange currentParagraph =
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
354
|
+
|
|
355
|
+
NSRange currentParagraph =
|
|
356
|
+
[fullText paragraphRangeForRange:NSMakeRange(index, 0)];
|
|
357
|
+
if (currentParagraph.location > 0) {
|
|
358
|
+
OrderedListStyle *olStyle =
|
|
359
|
+
input->stylesDict[@([OrderedListStyle getStyleType])];
|
|
360
|
+
|
|
259
361
|
NSInteger prevParagraphsCount = 0;
|
|
260
|
-
NSInteger recentParagraphLocation =
|
|
261
|
-
|
|
362
|
+
NSInteger recentParagraphLocation =
|
|
363
|
+
[fullText
|
|
364
|
+
paragraphRangeForRange:NSMakeRange(currentParagraph.location - 1,
|
|
365
|
+
0)]
|
|
366
|
+
.location;
|
|
367
|
+
|
|
262
368
|
// seek for previous lists
|
|
263
|
-
while(true) {
|
|
264
|
-
if([olStyle detectStyle:NSMakeRange(recentParagraphLocation, 0)]) {
|
|
369
|
+
while (true) {
|
|
370
|
+
if ([olStyle detectStyle:NSMakeRange(recentParagraphLocation, 0)]) {
|
|
265
371
|
prevParagraphsCount += 1;
|
|
266
|
-
|
|
267
|
-
if(recentParagraphLocation > 0) {
|
|
268
|
-
recentParagraphLocation =
|
|
372
|
+
|
|
373
|
+
if (recentParagraphLocation > 0) {
|
|
374
|
+
recentParagraphLocation =
|
|
375
|
+
[fullText
|
|
376
|
+
paragraphRangeForRange:NSMakeRange(
|
|
377
|
+
recentParagraphLocation - 1, 0)]
|
|
378
|
+
.location;
|
|
269
379
|
} else {
|
|
270
380
|
break;
|
|
271
381
|
}
|
|
@@ -273,10 +383,10 @@ static void const *kInputKey = &kInputKey;
|
|
|
273
383
|
break;
|
|
274
384
|
}
|
|
275
385
|
}
|
|
276
|
-
|
|
386
|
+
|
|
277
387
|
itemNumber = prevParagraphsCount + 1;
|
|
278
388
|
}
|
|
279
|
-
|
|
389
|
+
|
|
280
390
|
return [NSString stringWithFormat:@"%ld.", (long)(itemNumber)];
|
|
281
391
|
} else {
|
|
282
392
|
return @"•";
|
|
@@ -1,56 +1,63 @@
|
|
|
1
1
|
#import "MentionStyleProps.h"
|
|
2
|
-
#import <React/RCTConversions.h>
|
|
3
2
|
#import "StringExtension.h"
|
|
3
|
+
#import <React/RCTConversions.h>
|
|
4
4
|
|
|
5
5
|
@implementation MentionStyleProps
|
|
6
6
|
|
|
7
|
-
+ (MentionStyleProps *)getSingleMentionStylePropsFromFollyDynamic:
|
|
7
|
+
+ (MentionStyleProps *)getSingleMentionStylePropsFromFollyDynamic:
|
|
8
|
+
(folly::dynamic)folly {
|
|
8
9
|
MentionStyleProps *nativeProps = [[MentionStyleProps alloc] init];
|
|
9
|
-
|
|
10
|
-
if(folly["color"].isNumber()) {
|
|
11
|
-
facebook::react::SharedColor color = facebook::react::SharedColor(
|
|
10
|
+
|
|
11
|
+
if (folly["color"].isNumber()) {
|
|
12
|
+
facebook::react::SharedColor color = facebook::react::SharedColor(
|
|
13
|
+
facebook::react::Color(folly["color"].asInt()));
|
|
12
14
|
nativeProps.color = RCTUIColorFromSharedColor(color);
|
|
13
15
|
} else {
|
|
14
16
|
nativeProps.color = [UIColor blueColor];
|
|
15
17
|
}
|
|
16
|
-
|
|
17
|
-
if(folly["backgroundColor"].isNumber()) {
|
|
18
|
-
facebook::react::SharedColor bgColor = facebook::react::SharedColor(
|
|
18
|
+
|
|
19
|
+
if (folly["backgroundColor"].isNumber()) {
|
|
20
|
+
facebook::react::SharedColor bgColor = facebook::react::SharedColor(
|
|
21
|
+
facebook::react::Color(folly["backgroundColor"].asInt()));
|
|
19
22
|
nativeProps.backgroundColor = RCTUIColorFromSharedColor(bgColor);
|
|
20
23
|
} else {
|
|
21
24
|
nativeProps.backgroundColor = [UIColor yellowColor];
|
|
22
25
|
}
|
|
23
|
-
|
|
24
|
-
if(folly["textDecorationLine"].isString()) {
|
|
26
|
+
|
|
27
|
+
if (folly["textDecorationLine"].isString()) {
|
|
25
28
|
std::string textDecorationLine = folly["textDecorationLine"].asString();
|
|
26
|
-
nativeProps.decorationLine = [[NSString fromCppString:textDecorationLine]
|
|
29
|
+
nativeProps.decorationLine = [[NSString fromCppString:textDecorationLine]
|
|
30
|
+
isEqualToString:DecorationUnderline]
|
|
31
|
+
? DecorationUnderline
|
|
32
|
+
: DecorationNone;
|
|
27
33
|
} else {
|
|
28
34
|
nativeProps.decorationLine = DecorationUnderline;
|
|
29
35
|
}
|
|
30
|
-
|
|
36
|
+
|
|
31
37
|
return nativeProps;
|
|
32
38
|
}
|
|
33
39
|
|
|
34
40
|
+ (NSDictionary *)getSinglePropsFromFollyDynamic:(folly::dynamic)folly {
|
|
35
|
-
MentionStyleProps *nativeProps =
|
|
41
|
+
MentionStyleProps *nativeProps =
|
|
42
|
+
[MentionStyleProps getSingleMentionStylePropsFromFollyDynamic:folly];
|
|
36
43
|
// the single props need to be somehow distinguishable in config
|
|
37
|
-
NSDictionary *dict = @{@"all": nativeProps};
|
|
44
|
+
NSDictionary *dict = @{@"all" : nativeProps};
|
|
38
45
|
return dict;
|
|
39
46
|
}
|
|
40
47
|
|
|
41
48
|
+ (NSDictionary *)getComplexPropsFromFollyDynamic:(folly::dynamic)folly {
|
|
42
49
|
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
|
43
|
-
|
|
44
|
-
for(const auto&
|
|
45
|
-
if(obj.first.isString() && obj.second.isObject()) {
|
|
50
|
+
|
|
51
|
+
for (const auto &obj : folly.items()) {
|
|
52
|
+
if (obj.first.isString() && obj.second.isObject()) {
|
|
46
53
|
std::string key = obj.first.asString();
|
|
47
|
-
MentionStyleProps *props = [MentionStyleProps
|
|
54
|
+
MentionStyleProps *props = [MentionStyleProps
|
|
55
|
+
getSingleMentionStylePropsFromFollyDynamic:obj.second];
|
|
48
56
|
dict[[NSString fromCppString:key]] = props;
|
|
49
57
|
}
|
|
50
58
|
}
|
|
51
|
-
|
|
59
|
+
|
|
52
60
|
return dict;
|
|
53
61
|
}
|
|
54
62
|
|
|
55
63
|
@end
|
|
56
|
-
|