-
Notifications
You must be signed in to change notification settings - Fork 66
Expand file tree
/
Copy pathEnrichedTextInputViewShadowNode.mm
More file actions
114 lines (95 loc) · 3.92 KB
/
Copy pathEnrichedTextInputViewShadowNode.mm
File metadata and controls
114 lines (95 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#import "EnrichedTextInputViewShadowNode.h"
#import <EnrichedTextInputView.h>
#import <react/utils/ManagedObjectWrapper.h>
#import <yoga/Yoga.h>
#import <React/RCTShadowView+Layout.h>
#import "CoreText/CoreText.h"
namespace facebook::react {
extern const char EnrichedTextInputViewComponentName[] = "EnrichedTextInputView";
id EnrichedTextInputViewShadowNode::mockTextInputView_ = nullptr;
EnrichedTextInputViewShadowNode::EnrichedTextInputViewShadowNode(
const ShadowNodeFragment& fragment,
const ShadowNodeFamily::Shared& family,
ShadowNodeTraits traits
): ConcreteViewShadowNode(fragment, family, traits) {
localForceHeightRecalculationCounter_ = 0;
// mock text input needs to be initialized on the main thread
if([NSThread isMainThread]) {
setupMockTextInputView_();
} else {
dispatch_sync(dispatch_get_main_queue(), ^{
setupMockTextInputView_();
});
}
}
// mock input is used for the first measure calls that need to be done when the real input isn't defined yet
void EnrichedTextInputViewShadowNode::setupMockTextInputView_() {
// it's rendered far away from the viewport
const int veryFarAway = 20000;
const int mockSize = 1000;
mockTextInputView_ = [[EnrichedTextInputView alloc] initWithFrame:(CGRectMake(veryFarAway, veryFarAway, mockSize, mockSize))];
const auto props = this->getProps();
((EnrichedTextInputView *)mockTextInputView_)->blockEmitting = YES;
[mockTextInputView_ updateProps:props oldProps:nullptr];
}
EnrichedTextInputViewShadowNode::EnrichedTextInputViewShadowNode(
const ShadowNode& sourceShadowNode,
const ShadowNodeFragment& fragment
): ConcreteViewShadowNode(sourceShadowNode, fragment) {
dirtyLayoutIfNeeded();
}
void EnrichedTextInputViewShadowNode::dirtyLayoutIfNeeded() {
const auto state = this->getStateData();
const int receivedCounter = state.getForceHeightRecalculationCounter();
if(receivedCounter > localForceHeightRecalculationCounter_) {
localForceHeightRecalculationCounter_ = receivedCounter;
YGNodeMarkDirty(&yogaNode_);
}
}
Size EnrichedTextInputViewShadowNode::measureContent(const LayoutContext& layoutContext, const LayoutConstraints& layoutConstraints) const {
const auto state = this->getStateData();
const auto componentRef = state.getComponentViewRef();
RCTInternalGenericWeakWrapper *weakWrapper = (RCTInternalGenericWeakWrapper *)unwrapManagedObject(componentRef);
if(weakWrapper != nullptr) {
id componentObject = weakWrapper.object;
EnrichedTextInputView *typedComponentObject = (EnrichedTextInputView *) componentObject;
if(typedComponentObject != nullptr) {
// remove the mock input on the first render with a defined real input
if(mockTextInputView_ != nullptr) {
mockTextInputView_ = nullptr;
}
__block CGSize estimatedSize;
// synchronously dispatch to main thread if needed
if([NSThread isMainThread]) {
estimatedSize = [typedComponentObject measureSize:layoutConstraints.maximumSize.width];
} else {
dispatch_sync(dispatch_get_main_queue(), ^{
estimatedSize = [typedComponentObject measureSize:layoutConstraints.maximumSize.width];
});
}
return {
estimatedSize.width,
MIN(estimatedSize.height, layoutConstraints.maximumSize.height)
};
}
} else {
if(mockTextInputView_ == nullptr) {
return Size();
}
__block CGSize estimatedSize;
// synchronously dispatch to main thread if needed
if([NSThread isMainThread]) {
estimatedSize = [mockTextInputView_ measureSize:layoutConstraints.maximumSize.width];
} else {
dispatch_sync(dispatch_get_main_queue(), ^{
estimatedSize = [mockTextInputView_ measureSize:layoutConstraints.maximumSize.width];
});
}
return {
estimatedSize.width,
MIN(estimatedSize.height, layoutConstraints.maximumSize.height)
};
}
return Size();
}
} // namespace facebook::react