react-native-enriched 0.1.6 → 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 +4 -14
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +4 -1
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +2 -1
- 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/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.h +0 -45
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +111 -2
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +9 -3
- package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewPackage.kt +2 -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 +42 -1
- 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 +135 -9
- 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 +13 -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/spans/utils/ForceRedrawSpan.kt +13 -0
- package/android/src/main/java/com/swmansion/enriched/styles/HtmlStyle.kt +80 -9
- package/android/src/main/java/com/swmansion/enriched/styles/InlineStyles.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +188 -5
- package/android/src/main/java/com/swmansion/enriched/styles/ParametrizedStyles.kt +57 -30
- package/android/src/main/java/com/swmansion/enriched/utils/AsyncDrawable.kt +91 -0
- package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +24 -13
- package/android/src/main/java/com/swmansion/enriched/utils/ResourceManager.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedSpanWatcher.kt +3 -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/android/src/main/res/drawable/broken_image.xml +10 -0
- package/ios/EnrichedTextInputView.h +27 -12
- package/ios/EnrichedTextInputView.mm +906 -547
- 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 +12 -6
- package/ios/config/InputConfig.mm +71 -33
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +10 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +7 -0
- package/ios/generated/RNEnrichedTextInputViewSpec/Props.h +0 -45
- package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +41 -4
- package/ios/inputParser/InputParser.h +5 -5
- package/ios/inputParser/InputParser.mm +867 -333
- 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 -24
- package/ios/internals/EnrichedTextInputViewShadowNode.mm +64 -47
- package/ios/internals/EnrichedTextInputViewState.h +3 -1
- package/ios/styles/BlockQuoteStyle.mm +192 -142
- package/ios/styles/BoldStyle.mm +96 -62
- package/ios/styles/CodeBlockStyle.mm +304 -0
- package/ios/styles/H1Style.mm +10 -3
- package/ios/styles/H2Style.mm +10 -3
- package/ios/styles/H3Style.mm +10 -3
- package/ios/styles/HeadingStyleBase.mm +129 -84
- package/ios/styles/ImageStyle.mm +160 -0
- package/ios/styles/InlineCodeStyle.mm +149 -84
- package/ios/styles/ItalicStyle.mm +77 -51
- package/ios/styles/LinkStyle.mm +353 -224
- package/ios/styles/MentionStyle.mm +434 -220
- package/ios/styles/OrderedListStyle.mm +172 -105
- package/ios/styles/StrikethroughStyle.mm +53 -34
- package/ios/styles/UnderlineStyle.mm +69 -45
- package/ios/styles/UnorderedListStyle.mm +170 -105
- package/ios/utils/BaseStyleProtocol.h +3 -2
- package/ios/utils/ColorExtension.mm +7 -5
- package/ios/utils/FontExtension.mm +42 -27
- package/ios/utils/ImageData.h +10 -0
- package/ios/utils/ImageData.mm +4 -0
- package/ios/utils/LayoutManagerExtension.h +1 -1
- package/ios/utils/LayoutManagerExtension.mm +334 -109
- 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 -38
- package/ios/utils/OccurenceUtils.mm +177 -107
- package/ios/utils/ParagraphAttributesUtils.h +6 -1
- package/ios/utils/ParagraphAttributesUtils.mm +152 -41
- 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 +35 -11
- 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 +153 -75
- package/lib/module/EnrichedTextInput.js +41 -3
- package/lib/module/EnrichedTextInput.js.map +1 -1
- package/lib/module/EnrichedTextInputNativeComponent.ts +17 -5
- package/lib/module/normalizeHtmlStyle.js +0 -4
- package/lib/module/normalizeHtmlStyle.js.map +1 -1
- package/lib/typescript/src/EnrichedTextInput.d.ts +2 -5
- package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +7 -5
- package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/normalizeHtmlStyle.d.ts.map +1 -1
- package/package.json +8 -1
- package/src/EnrichedTextInput.tsx +48 -7
- package/src/EnrichedTextInputNativeComponent.ts +17 -5
- package/src/normalizeHtmlStyle.ts +0 -4
|
@@ -1,114 +1,155 @@
|
|
|
1
1
|
#import "InputTextView.h"
|
|
2
2
|
#import "EnrichedTextInputView.h"
|
|
3
3
|
#import "StringExtension.h"
|
|
4
|
-
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
|
|
5
4
|
#import "TextInsertionUtils.h"
|
|
5
|
+
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
|
|
6
6
|
|
|
7
7
|
@implementation InputTextView
|
|
8
8
|
|
|
9
9
|
- (void)copy:(id)sender {
|
|
10
10
|
EnrichedTextInputView *typedInput = (EnrichedTextInputView *)_input;
|
|
11
|
-
if(typedInput == nullptr) {
|
|
12
|
-
|
|
11
|
+
if (typedInput == nullptr) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
13
15
|
// remove zero width spaces before copying the text
|
|
14
|
-
NSString *plainText = [typedInput->textView.textStorage.string
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
NSString *plainText = [typedInput->textView.textStorage.string
|
|
17
|
+
substringWithRange:typedInput->textView.selectedRange];
|
|
18
|
+
NSString *fixedPlainText =
|
|
19
|
+
[plainText stringByReplacingOccurrencesOfString:@"\u200B" withString:@""];
|
|
20
|
+
|
|
21
|
+
NSString *parsedHtml = [typedInput->parser
|
|
22
|
+
parseToHtmlFromRange:typedInput->textView.selectedRange];
|
|
23
|
+
|
|
24
|
+
NSMutableAttributedString *attrStr = [[typedInput->textView.textStorage
|
|
25
|
+
attributedSubstringFromRange:typedInput->textView.selectedRange]
|
|
26
|
+
mutableCopy];
|
|
20
27
|
NSRange fullAttrStrRange = NSMakeRange(0, attrStr.length);
|
|
21
|
-
[attrStr.mutableString replaceOccurrencesOfString:@"\u200B"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
[attrStr.mutableString replaceOccurrencesOfString:@"\u200B"
|
|
29
|
+
withString:@""
|
|
30
|
+
options:0
|
|
31
|
+
range:fullAttrStrRange];
|
|
32
|
+
|
|
33
|
+
NSData *rtfData =
|
|
34
|
+
[attrStr dataFromRange:NSMakeRange(0, attrStr.length)
|
|
35
|
+
documentAttributes:@{
|
|
36
|
+
NSDocumentTypeDocumentAttribute : NSRTFTextDocumentType
|
|
37
|
+
}
|
|
38
|
+
error:nullptr];
|
|
39
|
+
|
|
28
40
|
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
|
|
29
|
-
[pasteboard setItems:@[@{
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
41
|
+
[pasteboard setItems:@[ @{
|
|
42
|
+
UTTypeUTF8PlainText.identifier : fixedPlainText,
|
|
43
|
+
UTTypeHTML.identifier : parsedHtml,
|
|
44
|
+
UTTypeRTF.identifier : rtfData
|
|
45
|
+
} ]];
|
|
34
46
|
}
|
|
35
47
|
|
|
36
48
|
- (void)paste:(id)sender {
|
|
37
49
|
EnrichedTextInputView *typedInput = (EnrichedTextInputView *)_input;
|
|
38
|
-
if(typedInput == nullptr) {
|
|
50
|
+
if (typedInput == nullptr) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
39
53
|
|
|
40
54
|
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
|
|
41
55
|
NSArray<NSString *> *pasteboardTypes = pasteboard.pasteboardTypes;
|
|
42
56
|
NSRange currentRange = typedInput->textView.selectedRange;
|
|
43
|
-
|
|
44
|
-
if([pasteboardTypes containsObject:UTTypeHTML.identifier]) {
|
|
57
|
+
|
|
58
|
+
if ([pasteboardTypes containsObject:UTTypeHTML.identifier]) {
|
|
45
59
|
// we try processing the html contents
|
|
46
|
-
|
|
60
|
+
|
|
47
61
|
NSString *htmlString;
|
|
48
62
|
id htmlValue = [pasteboard valueForPasteboardType:UTTypeHTML.identifier];
|
|
49
|
-
|
|
50
|
-
if([htmlValue isKindOfClass:[NSData class]]) {
|
|
51
|
-
htmlString = [[NSString alloc]initWithData:htmlValue
|
|
52
|
-
|
|
63
|
+
|
|
64
|
+
if ([htmlValue isKindOfClass:[NSData class]]) {
|
|
65
|
+
htmlString = [[NSString alloc] initWithData:htmlValue
|
|
66
|
+
encoding:NSUTF8StringEncoding];
|
|
67
|
+
} else if ([htmlValue isKindOfClass:[NSString class]]) {
|
|
53
68
|
htmlString = htmlValue;
|
|
54
69
|
}
|
|
55
|
-
|
|
70
|
+
|
|
56
71
|
// validate the html
|
|
57
|
-
NSString *initiallyProcessedHtml =
|
|
58
|
-
|
|
59
|
-
|
|
72
|
+
NSString *initiallyProcessedHtml =
|
|
73
|
+
[typedInput->parser initiallyProcessHtml:htmlString];
|
|
74
|
+
|
|
75
|
+
if (initiallyProcessedHtml != nullptr) {
|
|
60
76
|
// valid html, let's apply it
|
|
61
77
|
currentRange.length > 0
|
|
62
|
-
|
|
63
|
-
|
|
78
|
+
? [typedInput->parser replaceFromHtml:initiallyProcessedHtml
|
|
79
|
+
range:currentRange]
|
|
80
|
+
: [typedInput->parser insertFromHtml:initiallyProcessedHtml
|
|
81
|
+
location:currentRange.location];
|
|
64
82
|
} else {
|
|
65
83
|
// fall back to plain text, otherwise do nothing
|
|
66
|
-
[self tryHandlingPlainTextItemsIn:pasteboard
|
|
84
|
+
[self tryHandlingPlainTextItemsIn:pasteboard
|
|
85
|
+
range:currentRange
|
|
86
|
+
input:typedInput];
|
|
67
87
|
}
|
|
68
88
|
} else {
|
|
69
|
-
[self tryHandlingPlainTextItemsIn:pasteboard
|
|
89
|
+
[self tryHandlingPlainTextItemsIn:pasteboard
|
|
90
|
+
range:currentRange
|
|
91
|
+
input:typedInput];
|
|
70
92
|
}
|
|
71
|
-
|
|
93
|
+
|
|
72
94
|
[typedInput anyTextMayHaveBeenModified];
|
|
73
95
|
}
|
|
74
96
|
|
|
75
|
-
- (void)tryHandlingPlainTextItemsIn:(UIPasteboard *)pasteboard
|
|
97
|
+
- (void)tryHandlingPlainTextItemsIn:(UIPasteboard *)pasteboard
|
|
98
|
+
range:(NSRange)range
|
|
99
|
+
input:(EnrichedTextInputView *)input {
|
|
76
100
|
NSArray *existingTypes = pasteboard.pasteboardTypes;
|
|
77
|
-
NSArray *handledTypes = @[
|
|
101
|
+
NSArray *handledTypes = @[
|
|
102
|
+
UTTypeUTF8PlainText.identifier, UTTypePlainText.identifier,
|
|
103
|
+
UTTypeURL.identifier
|
|
104
|
+
];
|
|
78
105
|
NSString *plainText;
|
|
79
|
-
|
|
80
|
-
for(NSString *type in handledTypes) {
|
|
81
|
-
if(![existingTypes containsObject:type]) {
|
|
106
|
+
|
|
107
|
+
for (NSString *type in handledTypes) {
|
|
108
|
+
if (![existingTypes containsObject:type]) {
|
|
82
109
|
continue;
|
|
83
110
|
}
|
|
84
|
-
|
|
111
|
+
|
|
85
112
|
id value = [pasteboard valueForPasteboardType:type];
|
|
86
|
-
|
|
87
|
-
if([value isKindOfClass:[NSData class]]) {
|
|
88
|
-
plainText = [[NSString alloc]initWithData:value
|
|
89
|
-
|
|
113
|
+
|
|
114
|
+
if ([value isKindOfClass:[NSData class]]) {
|
|
115
|
+
plainText = [[NSString alloc] initWithData:value
|
|
116
|
+
encoding:NSUTF8StringEncoding];
|
|
117
|
+
} else if ([value isKindOfClass:[NSString class]]) {
|
|
90
118
|
plainText = (NSString *)value;
|
|
91
|
-
} else if([value isKindOfClass:[NSURL class]]) {
|
|
119
|
+
} else if ([value isKindOfClass:[NSURL class]]) {
|
|
92
120
|
plainText = [(NSURL *)value absoluteString];
|
|
93
121
|
}
|
|
94
122
|
}
|
|
95
|
-
|
|
96
|
-
if(!plainText) {
|
|
123
|
+
|
|
124
|
+
if (!plainText) {
|
|
97
125
|
return;
|
|
98
126
|
}
|
|
99
|
-
|
|
100
|
-
range.length > 0
|
|
101
|
-
|
|
102
|
-
|
|
127
|
+
|
|
128
|
+
range.length > 0 ? [TextInsertionUtils replaceText:plainText
|
|
129
|
+
at:range
|
|
130
|
+
additionalAttributes:nullptr
|
|
131
|
+
input:input
|
|
132
|
+
withSelection:YES]
|
|
133
|
+
: [TextInsertionUtils insertText:plainText
|
|
134
|
+
at:range.location
|
|
135
|
+
additionalAttributes:nullptr
|
|
136
|
+
input:input
|
|
137
|
+
withSelection:YES];
|
|
103
138
|
}
|
|
104
139
|
|
|
105
140
|
- (void)cut:(id)sender {
|
|
106
141
|
EnrichedTextInputView *typedInput = (EnrichedTextInputView *)_input;
|
|
107
|
-
if(typedInput == nullptr) {
|
|
108
|
-
|
|
142
|
+
if (typedInput == nullptr) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
109
146
|
[self copy:sender];
|
|
110
|
-
[TextInsertionUtils replaceText:@""
|
|
111
|
-
|
|
147
|
+
[TextInsertionUtils replaceText:@""
|
|
148
|
+
at:typedInput->textView.selectedRange
|
|
149
|
+
additionalAttributes:nullptr
|
|
150
|
+
input:typedInput
|
|
151
|
+
withSelection:YES];
|
|
152
|
+
|
|
112
153
|
[typedInput anyTextMayHaveBeenModified];
|
|
113
154
|
}
|
|
114
155
|
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
#pragma once
|
|
2
|
-
#include <
|
|
2
|
+
#include <ReactNativeEnriched/EnrichedTextInputViewShadowNode.h>
|
|
3
3
|
#include <ReactNativeEnriched/Props.h>
|
|
4
|
+
#include <react/debug/react_native_assert.h>
|
|
4
5
|
#include <react/renderer/core/ConcreteComponentDescriptor.h>
|
|
5
|
-
#include <ReactNativeEnriched/EnrichedTextInputViewShadowNode.h>
|
|
6
6
|
|
|
7
7
|
namespace facebook::react {
|
|
8
|
-
class EnrichedTextInputViewComponentDescriptor final
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
class EnrichedTextInputViewComponentDescriptor final
|
|
9
|
+
: public ConcreteComponentDescriptor<EnrichedTextInputViewShadowNode> {
|
|
10
|
+
public:
|
|
11
|
+
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
|
|
12
|
+
void adopt(ShadowNode &shadowNode) const override {
|
|
13
|
+
react_native_assert(
|
|
14
|
+
dynamic_cast<EnrichedTextInputViewShadowNode *>(&shadowNode));
|
|
15
|
+
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
16
|
+
}
|
|
15
17
|
};
|
|
16
18
|
|
|
17
19
|
} // namespace facebook::react
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#pragma once
|
|
2
|
+
#include <ReactNativeEnriched/EnrichedTextInputViewState.h>
|
|
2
3
|
#include <ReactNativeEnriched/EventEmitters.h>
|
|
3
4
|
#include <ReactNativeEnriched/Props.h>
|
|
4
|
-
#include <
|
|
5
|
+
#include <jsi/jsi.h>
|
|
5
6
|
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
|
|
6
7
|
#include <react/renderer/core/LayoutConstraints.h>
|
|
7
|
-
#include <jsi/jsi.h>
|
|
8
8
|
|
|
9
9
|
namespace facebook::react {
|
|
10
10
|
|
|
@@ -13,28 +13,32 @@ JSI_EXPORT extern const char EnrichedTextInputViewComponentName[];
|
|
|
13
13
|
/*
|
|
14
14
|
* `ShadowNode` for <EnrichedTextInputView> component.
|
|
15
15
|
*/
|
|
16
|
-
class EnrichedTextInputViewShadowNode
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
16
|
+
class EnrichedTextInputViewShadowNode
|
|
17
|
+
: public ConcreteViewShadowNode<
|
|
18
|
+
EnrichedTextInputViewComponentName, EnrichedTextInputViewProps,
|
|
19
|
+
EnrichedTextInputViewEventEmitter, EnrichedTextInputViewState> {
|
|
20
|
+
public:
|
|
21
|
+
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
22
|
+
EnrichedTextInputViewShadowNode(const ShadowNodeFragment &fragment,
|
|
23
|
+
const ShadowNodeFamily::Shared &family,
|
|
24
|
+
ShadowNodeTraits traits);
|
|
25
|
+
EnrichedTextInputViewShadowNode(const ShadowNode &sourceShadowNode,
|
|
26
|
+
const ShadowNodeFragment &fragment);
|
|
27
|
+
void dirtyLayoutIfNeeded();
|
|
28
|
+
Size
|
|
29
|
+
measureContent(const LayoutContext &layoutContext,
|
|
30
|
+
const LayoutConstraints &layoutConstraints) const override;
|
|
31
|
+
|
|
32
|
+
static ShadowNodeTraits BaseTraits() {
|
|
33
|
+
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
34
|
+
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
|
|
35
|
+
traits.set(ShadowNodeTraits::Trait::MeasurableYogaNode);
|
|
36
|
+
return traits;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private:
|
|
40
|
+
int localForceHeightRecalculationCounter_;
|
|
41
|
+
id setupMockTextInputView_() const;
|
|
38
42
|
};
|
|
39
43
|
|
|
40
44
|
} // namespace facebook::react
|
|
@@ -1,86 +1,103 @@
|
|
|
1
1
|
#import "EnrichedTextInputViewShadowNode.h"
|
|
2
|
+
#import "CoreText/CoreText.h"
|
|
2
3
|
#import <EnrichedTextInputView.h>
|
|
4
|
+
#import <React/RCTShadowView+Layout.h>
|
|
3
5
|
#import <react/utils/ManagedObjectWrapper.h>
|
|
4
6
|
#import <yoga/Yoga.h>
|
|
5
|
-
#import <React/RCTShadowView+Layout.h>
|
|
6
|
-
#import "CoreText/CoreText.h"
|
|
7
7
|
|
|
8
8
|
namespace facebook::react {
|
|
9
9
|
|
|
10
|
-
extern const char EnrichedTextInputViewComponentName[] =
|
|
10
|
+
extern const char EnrichedTextInputViewComponentName[] =
|
|
11
|
+
"EnrichedTextInputView";
|
|
11
12
|
|
|
12
13
|
EnrichedTextInputViewShadowNode::EnrichedTextInputViewShadowNode(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
): ConcreteViewShadowNode(fragment, family, traits) {
|
|
14
|
+
const ShadowNodeFragment &fragment, const ShadowNodeFamily::Shared &family,
|
|
15
|
+
ShadowNodeTraits traits)
|
|
16
|
+
: ConcreteViewShadowNode(fragment, family, traits) {
|
|
17
17
|
localForceHeightRecalculationCounter_ = 0;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
// mock input is used for the first measure calls that need to be done when the
|
|
21
|
+
// real input isn't defined yet
|
|
22
|
+
id EnrichedTextInputViewShadowNode::setupMockTextInputView_() const {
|
|
23
|
+
// it's rendered far away from the viewport
|
|
24
|
+
const int veryFarAway = 20000;
|
|
25
|
+
const int mockSize = 1000;
|
|
26
|
+
EnrichedTextInputView *mockTextInputView_ = [[EnrichedTextInputView alloc]
|
|
27
|
+
initWithFrame:(CGRectMake(veryFarAway, veryFarAway, mockSize, mockSize))];
|
|
28
|
+
const auto props = this->getProps();
|
|
29
|
+
mockTextInputView_->blockEmitting = YES;
|
|
30
|
+
[mockTextInputView_ updateProps:props oldProps:nullptr];
|
|
31
|
+
return mockTextInputView_;
|
|
32
|
+
}
|
|
33
|
+
|
|
20
34
|
EnrichedTextInputViewShadowNode::EnrichedTextInputViewShadowNode(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
): ConcreteViewShadowNode(sourceShadowNode, fragment) {
|
|
35
|
+
const ShadowNode &sourceShadowNode, const ShadowNodeFragment &fragment)
|
|
36
|
+
: ConcreteViewShadowNode(sourceShadowNode, fragment) {
|
|
24
37
|
dirtyLayoutIfNeeded();
|
|
25
38
|
}
|
|
26
39
|
|
|
27
40
|
void EnrichedTextInputViewShadowNode::dirtyLayoutIfNeeded() {
|
|
28
41
|
const auto state = this->getStateData();
|
|
29
42
|
const int receivedCounter = state.getForceHeightRecalculationCounter();
|
|
30
|
-
|
|
31
|
-
if(receivedCounter > localForceHeightRecalculationCounter_) {
|
|
43
|
+
|
|
44
|
+
if (receivedCounter > localForceHeightRecalculationCounter_) {
|
|
32
45
|
localForceHeightRecalculationCounter_ = receivedCounter;
|
|
33
46
|
YGNodeMarkDirty(&yogaNode_);
|
|
34
47
|
}
|
|
35
48
|
}
|
|
36
49
|
|
|
37
|
-
Size EnrichedTextInputViewShadowNode::measureContent(
|
|
50
|
+
Size EnrichedTextInputViewShadowNode::measureContent(
|
|
51
|
+
const LayoutContext &layoutContext,
|
|
52
|
+
const LayoutConstraints &layoutConstraints) const {
|
|
38
53
|
const auto state = this->getStateData();
|
|
39
54
|
const auto componentRef = state.getComponentViewRef();
|
|
40
|
-
RCTInternalGenericWeakWrapper *weakWrapper =
|
|
41
|
-
|
|
42
|
-
|
|
55
|
+
RCTInternalGenericWeakWrapper *weakWrapper =
|
|
56
|
+
(RCTInternalGenericWeakWrapper *)unwrapManagedObject(componentRef);
|
|
57
|
+
|
|
58
|
+
if (weakWrapper != nullptr) {
|
|
43
59
|
id componentObject = weakWrapper.object;
|
|
44
|
-
EnrichedTextInputView *typedComponentObject =
|
|
45
|
-
|
|
46
|
-
|
|
60
|
+
EnrichedTextInputView *typedComponentObject =
|
|
61
|
+
(EnrichedTextInputView *)componentObject;
|
|
62
|
+
|
|
63
|
+
if (typedComponentObject != nullptr) {
|
|
47
64
|
__block CGSize estimatedSize;
|
|
48
|
-
|
|
65
|
+
|
|
49
66
|
// synchronously dispatch to main thread if needed
|
|
50
|
-
if([NSThread isMainThread]) {
|
|
51
|
-
estimatedSize = [typedComponentObject
|
|
67
|
+
if ([NSThread isMainThread]) {
|
|
68
|
+
estimatedSize = [typedComponentObject
|
|
69
|
+
measureSize:layoutConstraints.maximumSize.width];
|
|
52
70
|
} else {
|
|
53
71
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
|
54
|
-
estimatedSize = [typedComponentObject
|
|
72
|
+
estimatedSize = [typedComponentObject
|
|
73
|
+
measureSize:layoutConstraints.maximumSize.width];
|
|
55
74
|
});
|
|
56
75
|
}
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
|
|
60
|
-
MIN(estimatedSize.height, layoutConstraints.maximumSize.height)
|
|
61
|
-
};
|
|
76
|
+
|
|
77
|
+
return {estimatedSize.width,
|
|
78
|
+
MIN(estimatedSize.height, layoutConstraints.maximumSize.height)};
|
|
62
79
|
}
|
|
63
80
|
} else {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
__block CGSize estimatedSize;
|
|
82
|
+
|
|
83
|
+
// synchronously dispatch to main thread if needed
|
|
84
|
+
if ([NSThread isMainThread]) {
|
|
85
|
+
EnrichedTextInputView *mockTextInputView = setupMockTextInputView_();
|
|
86
|
+
estimatedSize =
|
|
87
|
+
[mockTextInputView measureSize:layoutConstraints.maximumSize.width];
|
|
88
|
+
} else {
|
|
89
|
+
dispatch_sync(dispatch_get_main_queue(), ^{
|
|
90
|
+
EnrichedTextInputView *mockTextInputView = setupMockTextInputView_();
|
|
91
|
+
estimatedSize =
|
|
92
|
+
[mockTextInputView measureSize:layoutConstraints.maximumSize.width];
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return {estimatedSize.width,
|
|
97
|
+
MIN(estimatedSize.height, layoutConstraints.maximumSize.height)};
|
|
81
98
|
}
|
|
82
|
-
|
|
99
|
+
|
|
83
100
|
return Size();
|
|
84
101
|
}
|
|
85
|
-
|
|
102
|
+
|
|
86
103
|
} // namespace facebook::react
|
|
@@ -5,13 +5,15 @@ namespace facebook::react {
|
|
|
5
5
|
|
|
6
6
|
class EnrichedTextInputViewState {
|
|
7
7
|
public:
|
|
8
|
-
EnrichedTextInputViewState()
|
|
8
|
+
EnrichedTextInputViewState()
|
|
9
|
+
: forceHeightRecalculationCounter_(0), componentViewRef_(nullptr) {}
|
|
9
10
|
EnrichedTextInputViewState(int counter, std::shared_ptr<void> ref) {
|
|
10
11
|
forceHeightRecalculationCounter_ = counter;
|
|
11
12
|
componentViewRef_ = ref;
|
|
12
13
|
}
|
|
13
14
|
int getForceHeightRecalculationCounter() const;
|
|
14
15
|
std::shared_ptr<void> getComponentViewRef() const;
|
|
16
|
+
|
|
15
17
|
private:
|
|
16
18
|
int forceHeightRecalculationCounter_{};
|
|
17
19
|
std::shared_ptr<void> componentViewRef_{};
|