-
Notifications
You must be signed in to change notification settings - Fork 66
Expand file tree
/
Copy pathEnrichedTextInputViewShadowNode.mm
More file actions
103 lines (87 loc) · 3.62 KB
/
Copy pathEnrichedTextInputViewShadowNode.mm
File metadata and controls
103 lines (87 loc) · 3.62 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
#import "EnrichedTextInputViewShadowNode.h"
#import "CoreText/CoreText.h"
#import "EnrichedTextInputView.h"
#import <React/RCTShadowView+Layout.h>
#import <react/utils/ManagedObjectWrapper.h>
#import <yoga/Yoga.h>
namespace facebook::react {
extern const char EnrichedTextInputViewComponentName[] =
"EnrichedTextInputView";
EnrichedTextInputViewShadowNode::EnrichedTextInputViewShadowNode(
const ShadowNodeFragment &fragment, const ShadowNodeFamily::Shared &family,
ShadowNodeTraits traits)
: ConcreteViewShadowNode(fragment, family, traits) {
localForceHeightRecalculationCounter_ = 0;
}
// mock input is used for the first measure calls that need to be done when the
// real input isn't defined yet
id EnrichedTextInputViewShadowNode::setupMockTextInputView_() const {
// it's rendered far away from the viewport
const int veryFarAway = 20000;
const int mockSize = 1000;
EnrichedTextInputView *mockTextInputView_ = [[EnrichedTextInputView alloc]
initWithFrame:(CGRectMake(veryFarAway, veryFarAway, mockSize, mockSize))];
const auto props = this->getProps();
mockTextInputView_->blockEmitting = YES;
[mockTextInputView_ updateProps:props oldProps:nullptr];
return mockTextInputView_;
}
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) {
__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 {
__block CGSize estimatedSize;
// synchronously dispatch to main thread if needed
if ([NSThread isMainThread]) {
EnrichedTextInputView *mockTextInputView = setupMockTextInputView_();
estimatedSize =
[mockTextInputView measureSize:layoutConstraints.maximumSize.width];
} else {
dispatch_sync(dispatch_get_main_queue(), ^{
EnrichedTextInputView *mockTextInputView = setupMockTextInputView_();
estimatedSize =
[mockTextInputView measureSize:layoutConstraints.maximumSize.width];
});
}
return {estimatedSize.width,
MIN(estimatedSize.height, layoutConstraints.maximumSize.height)};
}
return Size();
}
} // namespace facebook::react