react-native-windows 0.76.11 → 0.76.13
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/Libraries/Components/Button.windows.js +3 -0
- package/Libraries/Components/ScrollView/ScrollView.windows.js +1959 -0
- package/Libraries/Components/View/View.windows.js +107 -56
- package/Libraries/Image/Image.windows.js +42 -21
- package/Libraries/Text/Text.d.ts +16 -1
- package/Microsoft.ReactNative/CompositionComponentView.idl +0 -5
- package/Microsoft.ReactNative/CompositionSwitcher.idl +4 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp +32 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +159 -4
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +11 -4
- package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +0 -4
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +22 -17
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +1 -27
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +0 -2
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +36 -11
- package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h +3 -0
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +50 -125
- package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +9 -6
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +31 -12
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +6 -1
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +2 -2
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +145 -19
- package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +13 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentDescriptor.h +0 -2
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +134 -11
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +6 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputEventEmitter.cpp +31 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputEventEmitter.h +14 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.cpp +6 -2
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.h +4 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.cpp +127 -109
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.h +28 -25
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.cpp +8 -18
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.h +12 -35
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +53 -11
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +10 -2
- package/Microsoft.ReactNative/Fabric/ImageRequestParams.cpp +26 -0
- package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +38 -8
- package/Microsoft.ReactNative/Fabric/WindowsImageManager.h +3 -1
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.cpp +206 -41
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.h +14 -0
- package/Microsoft.ReactNative/Modules/Animated/AnimationDriver.cpp +2 -1
- package/Microsoft.ReactNative/ReactNativeIsland.idl +3 -0
- package/Microsoft.ReactNative/Utils/ImageUtils.h +1 -0
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/NuGet.LockFile.props +1 -1
- package/PropertySheets/WebView2.props +1 -1
- package/PropertySheets/WinUI.props +1 -1
- package/Shared/Networking/WinRTWebSocketResource.cpp +82 -101
- package/Shared/Networking/WinRTWebSocketResource.h +91 -7
- package/Shared/Shared.vcxitems +3 -1
- package/Shared/Shared.vcxitems.filters +1 -0
- package/package.json +1 -1
|
@@ -24,6 +24,7 @@ WindowsTextInputProps::WindowsTextInputProps(
|
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
allowFontScaling(convertRawProp(context, rawProps, "allowFontScaling", sourceProps.allowFontScaling, {true})),
|
|
27
|
+
autoCorrect(convertRawProp(context, rawProps, "autoCorrect", sourceProps.autoCorrect, {true})),
|
|
27
28
|
clearTextOnFocus(convertRawProp(context, rawProps, "clearTextOnFocus", sourceProps.clearTextOnFocus, {false})),
|
|
28
29
|
editable(convertRawProp(context, rawProps, "editable", sourceProps.editable, {true})),
|
|
29
30
|
maxLength(convertRawProp(context, rawProps, "maxLength", sourceProps.maxLength, {0})),
|
|
@@ -36,7 +37,7 @@ WindowsTextInputProps::WindowsTextInputProps(
|
|
|
36
37
|
selection(convertRawProp(context, rawProps, "selection", sourceProps.selection, {})),
|
|
37
38
|
selectionColor(convertRawProp(context, rawProps, "selectionColor", sourceProps.selectionColor, {})),
|
|
38
39
|
selectTextOnFocus(convertRawProp(context, rawProps, "selectTextOnFocus", sourceProps.selectTextOnFocus, {false})),
|
|
39
|
-
spellCheck(convertRawProp(context, rawProps, "spellCheck", sourceProps.spellCheck, {
|
|
40
|
+
spellCheck(convertRawProp(context, rawProps, "spellCheck", sourceProps.spellCheck, {true})),
|
|
40
41
|
text(convertRawProp(context, rawProps, "text", sourceProps.text, {})),
|
|
41
42
|
mostRecentEventCount(
|
|
42
43
|
convertRawProp(context, rawProps, "mostRecentEventCount", sourceProps.mostRecentEventCount, {0})),
|
|
@@ -47,7 +48,10 @@ WindowsTextInputProps::WindowsTextInputProps(
|
|
|
47
48
|
autoCapitalize(convertRawProp(context, rawProps, "autoCapitalize", sourceProps.autoCapitalize, {})),
|
|
48
49
|
clearTextOnSubmit(convertRawProp(context, rawProps, "clearTextOnSubmit", sourceProps.clearTextOnSubmit, {false})),
|
|
49
50
|
submitKeyEvents(convertRawProp(context, rawProps, "submitKeyEvents", sourceProps.submitKeyEvents, {})),
|
|
50
|
-
autoFocus(convertRawProp(context, rawProps, "autoFocus", sourceProps.autoFocus, {false}))
|
|
51
|
+
autoFocus(convertRawProp(context, rawProps, "autoFocus", sourceProps.autoFocus, {false})),
|
|
52
|
+
textAlign(
|
|
53
|
+
convertRawProp(context, rawProps, "textAlign", sourceProps.textAlign, facebook::react::TextAlignment::Left)) {
|
|
54
|
+
}
|
|
51
55
|
|
|
52
56
|
void WindowsTextInputProps::setProp(
|
|
53
57
|
const PropsParserContext &context,
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
#pragma once
|
|
5
5
|
|
|
6
6
|
#include <react/components/rnwcore/Props.h>
|
|
7
|
+
#include <react/renderer/attributedstring/conversions.h>
|
|
7
8
|
#include <react/renderer/components/text/BaseTextProps.h>
|
|
8
9
|
#include <react/renderer/core/propsConversions.h>
|
|
9
10
|
|
|
@@ -96,6 +97,7 @@ class WindowsTextInputProps final : public ViewProps, public BaseTextProps {
|
|
|
96
97
|
setProp(const PropsParserContext &context, RawPropsPropNameHash hash, const char *propName, RawValue const &value);
|
|
97
98
|
|
|
98
99
|
bool allowFontScaling{true};
|
|
100
|
+
bool autoCorrect{true};
|
|
99
101
|
bool clearTextOnFocus{false};
|
|
100
102
|
bool editable{true};
|
|
101
103
|
int maxLength{0};
|
|
@@ -107,7 +109,7 @@ class WindowsTextInputProps final : public ViewProps, public BaseTextProps {
|
|
|
107
109
|
CompWindowsTextInputSelectionStruct selection{};
|
|
108
110
|
SharedColor selectionColor{};
|
|
109
111
|
bool selectTextOnFocus{false};
|
|
110
|
-
bool spellCheck{
|
|
112
|
+
bool spellCheck{true};
|
|
111
113
|
std::string text{};
|
|
112
114
|
int mostRecentEventCount{0};
|
|
113
115
|
bool secureTextEntry{false};
|
|
@@ -118,6 +120,7 @@ class WindowsTextInputProps final : public ViewProps, public BaseTextProps {
|
|
|
118
120
|
bool clearTextOnSubmit{false};
|
|
119
121
|
std::vector<CompWindowsTextInputSubmitKeyEventsStruct> submitKeyEvents{};
|
|
120
122
|
bool autoFocus{false};
|
|
123
|
+
facebook::react::TextAlignment textAlign{};
|
|
121
124
|
};
|
|
122
125
|
|
|
123
126
|
} // namespace facebook::react
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
#include "WindowsTextInputShadowNode.h"
|
|
5
5
|
|
|
6
|
-
#include <react/
|
|
6
|
+
#include <react/featureflags/ReactNativeFeatureFlags.h>
|
|
7
7
|
#include <react/renderer/attributedstring/AttributedStringBox.h>
|
|
8
8
|
#include <react/renderer/attributedstring/TextAttributes.h>
|
|
9
9
|
#include <react/renderer/components/text/BaseTextShadowNode.h>
|
|
@@ -12,38 +12,33 @@
|
|
|
12
12
|
#include <react/renderer/core/conversions.h>
|
|
13
13
|
#include <react/renderer/textlayoutmanager/TextLayoutContext.h>
|
|
14
14
|
|
|
15
|
-
#include <utility>
|
|
16
|
-
|
|
17
15
|
namespace facebook::react {
|
|
18
16
|
|
|
19
17
|
extern const char WindowsTextInputComponentName[] = "WindowsTextInput";
|
|
20
18
|
|
|
21
|
-
void WindowsTextInputShadowNode::
|
|
19
|
+
void WindowsTextInputShadowNode::setTextLayoutManager(std::shared_ptr<const TextLayoutManager> textLayoutManager) {
|
|
22
20
|
ensureUnsealed();
|
|
23
|
-
|
|
21
|
+
textLayoutManager_ = std::move(textLayoutManager);
|
|
24
22
|
}
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
// shadow of the text which results in weird artifacts.
|
|
36
|
-
childTextAttributes.backgroundColor = HostPlatformColor::UndefinedColor;
|
|
24
|
+
Size WindowsTextInputShadowNode::measureContent(
|
|
25
|
+
const LayoutContext &layoutContext,
|
|
26
|
+
const LayoutConstraints &layoutConstraints) const {
|
|
27
|
+
// Layout is called right after measure.
|
|
28
|
+
// Measure is marked as `const`, and `layout` is not; so State can be updated
|
|
29
|
+
// during layout, but not during `measure`. If State is out-of-date in layout,
|
|
30
|
+
// it's too late: measure will have already operated on old State. Thus, we
|
|
31
|
+
// use the same value here that we *will* use in layout to update the state.
|
|
32
|
+
AttributedString attributedString = getMostRecentAttributedString(layoutContext);
|
|
37
33
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
if (attributedString.isEmpty()) {
|
|
35
|
+
attributedString = getPlaceholderAttributedString(layoutContext);
|
|
36
|
+
}
|
|
41
37
|
|
|
42
38
|
// BaseTextShadowNode only gets children. We must detect and prepend text
|
|
43
39
|
// value attributes manually.
|
|
44
40
|
if (!getConcreteProps().text.empty()) {
|
|
45
41
|
auto textAttributes = TextAttributes::defaultTextAttributes();
|
|
46
|
-
textAttributes.fontSizeMultiplier = layoutContext.fontSizeMultiplier;
|
|
47
42
|
textAttributes.apply(getConcreteProps().textAttributes);
|
|
48
43
|
auto fragment = AttributedString::Fragment{};
|
|
49
44
|
fragment.string = getConcreteProps().text;
|
|
@@ -53,59 +48,42 @@ AttributedString WindowsTextInputShadowNode::getAttributedString(const LayoutCon
|
|
|
53
48
|
// that effect.
|
|
54
49
|
fragment.textAttributes.backgroundColor = clearColor();
|
|
55
50
|
fragment.parentShadowView = ShadowView(*this);
|
|
56
|
-
attributedString.prependFragment(fragment);
|
|
51
|
+
attributedString.prependFragment(std::move(fragment));
|
|
57
52
|
}
|
|
58
53
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
// For measurement purposes, we want to make sure that there's at least a
|
|
63
|
-
// single character in the string so that the measured height is greater
|
|
64
|
-
// than zero. Otherwise, empty TextInputs with no placeholder don't
|
|
65
|
-
// display at all.
|
|
66
|
-
// TODO T67606511: We will redefine the measurement of empty strings as part
|
|
67
|
-
// of T67606511
|
|
68
|
-
AttributedString WindowsTextInputShadowNode::getPlaceholderAttributedString(const LayoutContext &layoutContext) const {
|
|
69
|
-
// Return placeholder text, since text and children are empty.
|
|
70
|
-
auto textAttributedString = AttributedString{};
|
|
71
|
-
auto fragment = AttributedString::Fragment{};
|
|
72
|
-
fragment.string = getConcreteProps().placeholder;
|
|
73
|
-
|
|
74
|
-
if (fragment.string.empty()) {
|
|
75
|
-
fragment.string = BaseTextShadowNode::getEmptyPlaceholder();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
auto textAttributes = TextAttributes::defaultTextAttributes();
|
|
79
|
-
textAttributes.fontSizeMultiplier = layoutContext.fontSizeMultiplier;
|
|
80
|
-
textAttributes.apply(getConcreteProps().textAttributes);
|
|
81
|
-
|
|
82
|
-
// If there's no text, it's possible that this Fragment isn't actually
|
|
83
|
-
// appended to the AttributedString (see implementation of appendFragment)
|
|
84
|
-
fragment.textAttributes = textAttributes;
|
|
85
|
-
fragment.parentShadowView = ShadowView(*this);
|
|
86
|
-
textAttributedString.appendFragment(fragment);
|
|
54
|
+
TextLayoutContext textLayoutContext;
|
|
55
|
+
textLayoutContext.pointScaleFactor = layoutContext.pointScaleFactor;
|
|
87
56
|
|
|
88
|
-
|
|
57
|
+
facebook::react::ParagraphAttributes paragraphAttributes{};
|
|
58
|
+
paragraphAttributes.maximumNumberOfLines = getConcreteProps().multiline ? 0 : 1;
|
|
59
|
+
return textLayoutManager_
|
|
60
|
+
->measure(AttributedStringBox{attributedString}, paragraphAttributes, textLayoutContext, layoutConstraints)
|
|
61
|
+
.size;
|
|
89
62
|
}
|
|
90
63
|
|
|
91
|
-
void WindowsTextInputShadowNode::
|
|
92
|
-
|
|
93
|
-
|
|
64
|
+
void WindowsTextInputShadowNode::layout(LayoutContext layoutContext) {
|
|
65
|
+
updateStateIfNeeded(layoutContext);
|
|
66
|
+
ConcreteViewShadowNode::layout(layoutContext);
|
|
94
67
|
}
|
|
95
68
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
69
|
+
LayoutConstraints WindowsTextInputShadowNode::getTextConstraints(const LayoutConstraints &layoutConstraints) const {
|
|
70
|
+
if (getConcreteProps().multiline) {
|
|
71
|
+
return layoutConstraints;
|
|
72
|
+
} else {
|
|
73
|
+
// A single line TextInput acts as a horizontal scroller of infinitely
|
|
74
|
+
// expandable text, so we want to measure the text as if it is allowed to
|
|
75
|
+
// infinitely expand horizontally, and later clamp to the constraints of the
|
|
76
|
+
// input.
|
|
77
|
+
return LayoutConstraints{
|
|
78
|
+
.minimumSize = layoutConstraints.minimumSize,
|
|
79
|
+
.maximumSize =
|
|
80
|
+
Size{
|
|
81
|
+
.width = std::numeric_limits<Float>::infinity(),
|
|
82
|
+
.height = layoutConstraints.maximumSize.height,
|
|
83
|
+
},
|
|
84
|
+
.layoutDirection = layoutConstraints.layoutDirection,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
109
87
|
}
|
|
110
88
|
|
|
111
89
|
void WindowsTextInputShadowNode::updateStateIfNeeded(const LayoutContext &layoutContext) {
|
|
@@ -146,59 +124,99 @@ void WindowsTextInputShadowNode::updateStateIfNeeded(const LayoutContext &layout
|
|
|
146
124
|
// so no changes are applied There's no way to prevent a state update from
|
|
147
125
|
// flowing to Java, so we just ensure it's a noop in those cases.
|
|
148
126
|
setStateData(facebook::react::WindowsTextInputState{
|
|
149
|
-
newEventCount
|
|
150
|
-
newAttributedString,
|
|
151
|
-
reactTreeAttributedString,
|
|
152
|
-
{},
|
|
153
|
-
state.defaultThemePaddingStart,
|
|
154
|
-
state.defaultThemePaddingEnd,
|
|
155
|
-
state.defaultThemePaddingTop,
|
|
156
|
-
state.defaultThemePaddingBottom});
|
|
127
|
+
AttributedStringBox(newAttributedString), reactTreeAttributedString, {}, newEventCount});
|
|
157
128
|
}
|
|
158
129
|
|
|
159
|
-
|
|
130
|
+
AttributedString WindowsTextInputShadowNode::getAttributedString(const LayoutContext &layoutContext) const {
|
|
131
|
+
// Use BaseTextShadowNode to get attributed string from children
|
|
160
132
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const LayoutConstraints &layoutConstraints) const {
|
|
164
|
-
if (getStateData().cachedAttributedStringId != 0) {
|
|
165
|
-
return m_textLayoutManager
|
|
166
|
-
->measureCachedSpannableById(
|
|
167
|
-
getStateData().cachedAttributedStringId,
|
|
168
|
-
{}, // TODO getConcreteProps().paragraphAttributes
|
|
169
|
-
layoutConstraints)
|
|
170
|
-
.size;
|
|
171
|
-
}
|
|
133
|
+
auto childTextAttributes = TextAttributes::defaultTextAttributes();
|
|
134
|
+
childTextAttributes.fontSizeMultiplier = layoutContext.fontSizeMultiplier;
|
|
172
135
|
|
|
173
|
-
|
|
174
|
-
//
|
|
175
|
-
//
|
|
176
|
-
//
|
|
177
|
-
|
|
178
|
-
AttributedString attributedString = getMostRecentAttributedString(layoutContext);
|
|
136
|
+
childTextAttributes.apply(getConcreteProps().textAttributes);
|
|
137
|
+
// Don't propagate the background color of the TextInput onto the attributed
|
|
138
|
+
// string. Android tries to render shadow of the background alongside the
|
|
139
|
+
// shadow of the text which results in weird artifacts.
|
|
140
|
+
childTextAttributes.backgroundColor = HostPlatformColor::UndefinedColor;
|
|
179
141
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
142
|
+
auto attributedString = AttributedString{};
|
|
143
|
+
auto attachments = BaseTextShadowNode::Attachments{};
|
|
144
|
+
BaseTextShadowNode::buildAttributedString(childTextAttributes, *this, attributedString, attachments);
|
|
183
145
|
|
|
184
|
-
|
|
185
|
-
|
|
146
|
+
// BaseTextShadowNode only gets children. We must detect and prepend text
|
|
147
|
+
// value attributes manually.
|
|
148
|
+
if (!getConcreteProps().text.empty()) {
|
|
149
|
+
auto textAttributes = TextAttributes::defaultTextAttributes();
|
|
150
|
+
textAttributes.fontSizeMultiplier = layoutContext.fontSizeMultiplier;
|
|
151
|
+
textAttributes.apply(getConcreteProps().textAttributes);
|
|
152
|
+
auto fragment = AttributedString::Fragment{};
|
|
153
|
+
fragment.string = getConcreteProps().text;
|
|
154
|
+
fragment.textAttributes = textAttributes;
|
|
155
|
+
// If the TextInput opacity is 0 < n < 1, the opacity of the TextInput and
|
|
156
|
+
// text value's background will stack. This is a hack/workaround to prevent
|
|
157
|
+
// that effect.
|
|
158
|
+
fragment.textAttributes.backgroundColor = clearColor();
|
|
159
|
+
fragment.parentShadowView = ShadowView(*this);
|
|
160
|
+
attributedString.prependFragment(std::move(fragment));
|
|
186
161
|
}
|
|
187
162
|
|
|
188
|
-
|
|
189
|
-
textLayoutContext.pointScaleFactor = layoutContext.pointScaleFactor;
|
|
190
|
-
return m_textLayoutManager
|
|
191
|
-
->measure(
|
|
192
|
-
AttributedStringBox{attributedString},
|
|
193
|
-
{}, // TODO getConcreteProps().paragraphAttributes,
|
|
194
|
-
textLayoutContext,
|
|
195
|
-
layoutConstraints)
|
|
196
|
-
.size;
|
|
163
|
+
return attributedString;
|
|
197
164
|
}
|
|
198
165
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
166
|
+
AttributedString WindowsTextInputShadowNode::getMostRecentAttributedString(const LayoutContext &layoutContext) const {
|
|
167
|
+
const auto &state = getStateData();
|
|
168
|
+
|
|
169
|
+
auto reactTreeAttributedString = getAttributedString(layoutContext);
|
|
170
|
+
|
|
171
|
+
// Sometimes the treeAttributedString will only differ from the state
|
|
172
|
+
// not by inherent properties (string or prop attributes), but by the frame of
|
|
173
|
+
// the parent which has changed Thus, we can't directly compare the entire
|
|
174
|
+
// AttributedString
|
|
175
|
+
bool treeAttributedStringChanged =
|
|
176
|
+
!state.reactTreeAttributedString.compareTextAttributesWithoutFrame(reactTreeAttributedString);
|
|
177
|
+
|
|
178
|
+
return (!treeAttributedStringChanged ? state.attributedStringBox.getValue() : reactTreeAttributedString);
|
|
202
179
|
}
|
|
203
180
|
|
|
181
|
+
// For measurement purposes, we want to make sure that there's at least a
|
|
182
|
+
// single character in the string so that the measured height is greater
|
|
183
|
+
// than zero. Otherwise, empty TextInputs with no placeholder don't
|
|
184
|
+
// display at all.
|
|
185
|
+
// TODO T67606511: We will redefine the measurement of empty strings as part
|
|
186
|
+
// of T67606511
|
|
187
|
+
AttributedString WindowsTextInputShadowNode::getPlaceholderAttributedString(const LayoutContext &layoutContext) const {
|
|
188
|
+
// Return placeholder text, since text and children are empty.
|
|
189
|
+
auto textAttributedString = AttributedString{};
|
|
190
|
+
auto fragment = AttributedString::Fragment{};
|
|
191
|
+
fragment.string = getConcreteProps().placeholder;
|
|
192
|
+
|
|
193
|
+
if (fragment.string.empty()) {
|
|
194
|
+
fragment.string = BaseTextShadowNode::getEmptyPlaceholder();
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
auto textAttributes = TextAttributes::defaultTextAttributes();
|
|
198
|
+
textAttributes.fontSizeMultiplier = layoutContext.fontSizeMultiplier;
|
|
199
|
+
textAttributes.apply(getConcreteProps().textAttributes);
|
|
200
|
+
|
|
201
|
+
// If there's no text, it's possible that this Fragment isn't actually
|
|
202
|
+
// appended to the AttributedString (see implementation of appendFragment)
|
|
203
|
+
fragment.textAttributes = textAttributes;
|
|
204
|
+
fragment.parentShadowView = ShadowView(*this);
|
|
205
|
+
textAttributedString.appendFragment(std::move(fragment));
|
|
206
|
+
|
|
207
|
+
return textAttributedString;
|
|
208
|
+
// TextLayoutContext textLayoutContext;
|
|
209
|
+
// textLayoutContext.pointScaleFactor = layoutContext.pointScaleFactor;
|
|
210
|
+
// auto textSize = textLayoutManager_
|
|
211
|
+
// ->measure(
|
|
212
|
+
// AttributedStringBox{attributedString},
|
|
213
|
+
// getConcreteProps().paragraphAttributes,
|
|
214
|
+
// textLayoutContext,
|
|
215
|
+
// textConstraints)
|
|
216
|
+
// .size;
|
|
217
|
+
// return layoutConstraints.clamp(textSize);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
#pragma mark - LayoutableShadowNode
|
|
221
|
+
|
|
204
222
|
} // namespace facebook::react
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
#include "WindowsTextInputProps.h"
|
|
10
10
|
#include "WindowsTextInputState.h"
|
|
11
11
|
|
|
12
|
+
#include <react/renderer/attributedstring/AttributedString.h>
|
|
12
13
|
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
|
|
13
14
|
#include <react/utils/ContextContainer.h>
|
|
14
15
|
|
|
15
|
-
#include <react/renderer/attributedstring/AttributedString.h>
|
|
16
16
|
#include <react/renderer/textlayoutmanager/TextLayoutManager.h>
|
|
17
17
|
|
|
18
18
|
namespace facebook::react {
|
|
@@ -28,56 +28,59 @@ class WindowsTextInputShadowNode final : public ConcreteViewShadowNode<
|
|
|
28
28
|
WindowsTextInputEventEmitter,
|
|
29
29
|
WindowsTextInputState> {
|
|
30
30
|
public:
|
|
31
|
+
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
32
|
+
|
|
31
33
|
static ShadowNodeTraits BaseTraits() {
|
|
32
34
|
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
33
35
|
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
|
|
36
|
+
traits.set(ShadowNodeTraits::Trait::MeasurableYogaNode);
|
|
34
37
|
traits.set(ShadowNodeTraits::Trait::BaselineYogaNode);
|
|
35
38
|
return traits;
|
|
36
39
|
}
|
|
37
40
|
|
|
38
|
-
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
39
|
-
|
|
40
|
-
void setContextContainer(ContextContainer *contextContainer);
|
|
41
|
-
|
|
42
|
-
/*
|
|
43
|
-
* Returns a `AttributedString` which represents text content of the node.
|
|
44
|
-
*/
|
|
45
|
-
AttributedString getAttributedString(const LayoutContext &layoutContext) const;
|
|
46
|
-
AttributedString getPlaceholderAttributedString(const LayoutContext &layoutContext) const;
|
|
47
|
-
|
|
48
41
|
/*
|
|
49
42
|
* Associates a shared TextLayoutManager with the node.
|
|
50
|
-
* `
|
|
51
|
-
* and construct `
|
|
43
|
+
* `TextInputShadowNode` uses the manager to measure text content
|
|
44
|
+
* and construct `TextInputState` objects.
|
|
52
45
|
*/
|
|
53
|
-
void setTextLayoutManager(
|
|
46
|
+
void setTextLayoutManager(std::shared_ptr<const TextLayoutManager> textLayoutManager);
|
|
54
47
|
|
|
55
48
|
#pragma mark - LayoutableShadowNode
|
|
56
|
-
|
|
49
|
+
protected:
|
|
57
50
|
Size measureContent(const LayoutContext &layoutContext, const LayoutConstraints &layoutConstraints) const override;
|
|
51
|
+
|
|
58
52
|
void layout(LayoutContext layoutContext) override;
|
|
59
53
|
|
|
60
|
-
|
|
61
|
-
|
|
54
|
+
Float baseline(const LayoutContext &layoutContext, Size size) const override {
|
|
55
|
+
// Calculate baseline as 80% of the text height
|
|
56
|
+
return size.height * 0.8f;
|
|
57
|
+
}
|
|
62
58
|
|
|
63
|
-
|
|
64
|
-
|
|
59
|
+
std::shared_ptr<const TextLayoutManager> textLayoutManager_;
|
|
60
|
+
|
|
61
|
+
/*
|
|
62
|
+
* Determines the constraints to use while measure the underlying text
|
|
65
63
|
*/
|
|
66
|
-
|
|
64
|
+
LayoutConstraints getTextConstraints(const LayoutConstraints &layoutConstraints) const;
|
|
67
65
|
|
|
66
|
+
private:
|
|
68
67
|
/*
|
|
69
68
|
* Creates a `State` object (with `AttributedText` and
|
|
70
69
|
* `TextLayoutManager`) if needed.
|
|
71
70
|
*/
|
|
72
71
|
void updateStateIfNeeded(const LayoutContext &layoutContext);
|
|
73
72
|
|
|
74
|
-
SharedTextLayoutManager m_textLayoutManager;
|
|
75
|
-
|
|
76
73
|
/*
|
|
77
|
-
*
|
|
78
|
-
* from the node.
|
|
74
|
+
* Returns a `AttributedString` which represents text content of the node.
|
|
79
75
|
*/
|
|
80
|
-
|
|
76
|
+
AttributedString getAttributedString(const LayoutContext &layoutContext) const;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Get the most up-to-date attributed string for measurement and State.
|
|
80
|
+
*/
|
|
81
|
+
AttributedString getMostRecentAttributedString(const LayoutContext &layoutContext) const;
|
|
82
|
+
|
|
83
|
+
AttributedString getPlaceholderAttributedString(const LayoutContext &layoutContext) const;
|
|
81
84
|
};
|
|
82
85
|
|
|
83
86
|
} // namespace facebook::react
|
|
@@ -4,31 +4,21 @@
|
|
|
4
4
|
|
|
5
5
|
#include "WindowsTextInputState.h"
|
|
6
6
|
|
|
7
|
-
#
|
|
8
|
-
#include <react/renderer/
|
|
9
|
-
#include <react/renderer/
|
|
10
|
-
#
|
|
11
|
-
|
|
12
|
-
#include <utility>
|
|
7
|
+
#ifdef ANDROID
|
|
8
|
+
#include <react/renderer/attributedstring/conversions.h>
|
|
9
|
+
#include <react/renderer/components/text/ParagraphState.h>
|
|
10
|
+
#endif
|
|
13
11
|
|
|
14
12
|
namespace facebook::react {
|
|
15
13
|
|
|
16
14
|
WindowsTextInputState::WindowsTextInputState(
|
|
17
|
-
|
|
18
|
-
AttributedString attributedString,
|
|
15
|
+
AttributedStringBox attributedStringBox,
|
|
19
16
|
AttributedString reactTreeAttributedString,
|
|
20
17
|
ParagraphAttributes paragraphAttributes,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
double defaultThemePaddingTop,
|
|
24
|
-
double defaultThemePaddingBottom)
|
|
25
|
-
: mostRecentEventCount(mostRecentEventCount),
|
|
26
|
-
attributedString(std::move(attributedString)),
|
|
18
|
+
int64_t mostRecentEventCount)
|
|
19
|
+
: attributedStringBox(std::move(attributedStringBox)),
|
|
27
20
|
reactTreeAttributedString(std::move(reactTreeAttributedString)),
|
|
28
21
|
paragraphAttributes(std::move(paragraphAttributes)),
|
|
29
|
-
|
|
30
|
-
defaultThemePaddingEnd(defaultThemePaddingEnd),
|
|
31
|
-
defaultThemePaddingTop(defaultThemePaddingTop),
|
|
32
|
-
defaultThemePaddingBottom(defaultThemePaddingBottom) {}
|
|
22
|
+
mostRecentEventCount(mostRecentEventCount) {}
|
|
33
23
|
|
|
34
24
|
} // namespace facebook::react
|
|
@@ -3,33 +3,29 @@
|
|
|
3
3
|
|
|
4
4
|
#pragma once
|
|
5
5
|
|
|
6
|
-
#include <
|
|
7
|
-
#include <react/renderer/attributedstring/AttributedString.h>
|
|
6
|
+
#include <react/renderer/attributedstring/AttributedStringBox.h>
|
|
8
7
|
#include <react/renderer/attributedstring/ParagraphAttributes.h>
|
|
9
|
-
#include <react/renderer/mapbuffer/MapBuffer.h>
|
|
10
|
-
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
|
|
11
8
|
#include <react/renderer/textlayoutmanager/TextLayoutManager.h>
|
|
12
9
|
|
|
13
10
|
namespace facebook::react {
|
|
14
11
|
|
|
15
12
|
/*
|
|
16
|
-
* State for <
|
|
13
|
+
* State for <TextInput> component.
|
|
17
14
|
*/
|
|
18
15
|
class WindowsTextInputState final {
|
|
19
16
|
public:
|
|
20
|
-
|
|
17
|
+
WindowsTextInputState() = default;
|
|
21
18
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
WindowsTextInputState(
|
|
20
|
+
AttributedStringBox attributedStringBox,
|
|
21
|
+
AttributedString reactTreeAttributedString,
|
|
22
|
+
ParagraphAttributes paragraphAttributes,
|
|
23
|
+
int64_t mostRecentEventCount);
|
|
27
24
|
|
|
28
25
|
/*
|
|
29
|
-
* All content of <TextInput> component
|
|
30
|
-
* Only set if changed from the React tree's perspective.
|
|
26
|
+
* All content of <TextInput> component.
|
|
31
27
|
*/
|
|
32
|
-
|
|
28
|
+
AttributedStringBox attributedStringBox;
|
|
33
29
|
|
|
34
30
|
/*
|
|
35
31
|
* All content of <TextInput> component represented as an `AttributedString`.
|
|
@@ -44,28 +40,9 @@ class WindowsTextInputState final {
|
|
|
44
40
|
* Represents all visual attributes of a paragraph of text represented as
|
|
45
41
|
* a ParagraphAttributes.
|
|
46
42
|
*/
|
|
47
|
-
ParagraphAttributes paragraphAttributes
|
|
43
|
+
ParagraphAttributes paragraphAttributes;
|
|
48
44
|
|
|
49
|
-
|
|
50
|
-
* Communicates Android theme padding back to the ShadowNode / Component
|
|
51
|
-
* Descriptor for layout.
|
|
52
|
-
*/
|
|
53
|
-
double defaultThemePaddingStart{NAN};
|
|
54
|
-
double defaultThemePaddingEnd{NAN};
|
|
55
|
-
double defaultThemePaddingTop{NAN};
|
|
56
|
-
double defaultThemePaddingBottom{NAN};
|
|
57
|
-
|
|
58
|
-
WindowsTextInputState(
|
|
59
|
-
int64_t mostRecentEventCount,
|
|
60
|
-
AttributedString attributedString,
|
|
61
|
-
AttributedString reactTreeAttributedString,
|
|
62
|
-
ParagraphAttributes paragraphAttributes,
|
|
63
|
-
double defaultThemePaddingStart,
|
|
64
|
-
double defaultThemePaddingEnd,
|
|
65
|
-
double defaultThemePaddingTop,
|
|
66
|
-
double defaultThemePaddingBottom);
|
|
67
|
-
|
|
68
|
-
WindowsTextInputState() = default;
|
|
45
|
+
int64_t mostRecentEventCount{0};
|
|
69
46
|
};
|
|
70
47
|
|
|
71
48
|
} // namespace facebook::react
|
|
@@ -115,7 +115,6 @@ void FabricUIManager::installFabricUIManager() noexcept {
|
|
|
115
115
|
|
|
116
116
|
m_scheduler = std::make_shared<facebook::react::Scheduler>(
|
|
117
117
|
toolbox, (/*animationDriver_ ? animationDriver_.get() :*/ nullptr), this);
|
|
118
|
-
m_surfaceManager = std::make_shared<facebook::react::SurfaceManager>(*m_scheduler);
|
|
119
118
|
}
|
|
120
119
|
|
|
121
120
|
const IComponentViewRegistry &FabricUIManager::GetViewRegistry() const noexcept {
|
|
@@ -143,17 +142,38 @@ void FabricUIManager::startSurface(
|
|
|
143
142
|
layoutContext.pointScaleFactor = rootView.ScaleFactor();
|
|
144
143
|
layoutContext.fontSizeMultiplier = rootView.FontSizeMultiplier();
|
|
145
144
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
145
|
+
{
|
|
146
|
+
std::unique_lock lock(m_handlerMutex);
|
|
147
|
+
auto surfaceHandler = facebook::react::SurfaceHandler{moduleName, surfaceId};
|
|
148
|
+
surfaceHandler.setContextContainer(m_scheduler->getContextContainer());
|
|
149
|
+
m_handlerRegistry.emplace(surfaceId, std::move(surfaceHandler));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
visit(surfaceId, [&](const facebook::react::SurfaceHandler &surfaceHandler) {
|
|
153
|
+
surfaceHandler.setProps(initialProps);
|
|
154
|
+
surfaceHandler.constraintLayout(layoutConstraints, layoutContext);
|
|
155
|
+
m_scheduler->registerSurface(surfaceHandler);
|
|
156
|
+
surfaceHandler.start();
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
void FabricUIManager::setProps(facebook::react::SurfaceId surfaceId, const folly::dynamic &props) const noexcept {
|
|
161
|
+
visit(surfaceId, [=](const facebook::react::SurfaceHandler &surfaceHandler) { surfaceHandler.setProps(props); });
|
|
153
162
|
}
|
|
154
163
|
|
|
155
164
|
void FabricUIManager::stopSurface(facebook::react::SurfaceId surfaceId) noexcept {
|
|
156
|
-
|
|
165
|
+
visit(surfaceId, [&](const facebook::react::SurfaceHandler &surfaceHandler) {
|
|
166
|
+
surfaceHandler.stop();
|
|
167
|
+
m_scheduler->unregisterSurface(surfaceHandler);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
{
|
|
171
|
+
std::unique_lock lock(m_handlerMutex);
|
|
172
|
+
|
|
173
|
+
auto iterator = m_handlerRegistry.find(surfaceId);
|
|
174
|
+
m_handlerRegistry.erase(iterator);
|
|
175
|
+
}
|
|
176
|
+
|
|
157
177
|
auto &rootDescriptor = m_registry.componentViewDescriptorWithTag(surfaceId);
|
|
158
178
|
rootDescriptor.view.as<winrt::Microsoft::ReactNative::Composition::implementation::RootComponentView>()->stop();
|
|
159
179
|
m_registry.enqueueComponentViewWithComponentHandle(
|
|
@@ -164,14 +184,36 @@ facebook::react::Size FabricUIManager::measureSurface(
|
|
|
164
184
|
facebook::react::SurfaceId surfaceId,
|
|
165
185
|
const facebook::react::LayoutConstraints &layoutConstraints,
|
|
166
186
|
const facebook::react::LayoutContext &layoutContext) const noexcept {
|
|
167
|
-
|
|
187
|
+
auto size = facebook::react::Size{};
|
|
188
|
+
|
|
189
|
+
visit(surfaceId, [&](const facebook::react::SurfaceHandler &surfaceHandler) {
|
|
190
|
+
size = surfaceHandler.measure(layoutConstraints, layoutContext);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
return size;
|
|
168
194
|
}
|
|
169
195
|
|
|
170
196
|
void FabricUIManager::constraintSurfaceLayout(
|
|
171
197
|
facebook::react::SurfaceId surfaceId,
|
|
172
198
|
const facebook::react::LayoutConstraints &layoutConstraints,
|
|
173
199
|
const facebook::react::LayoutContext &layoutContext) const noexcept {
|
|
174
|
-
|
|
200
|
+
visit(surfaceId, [=](const facebook::react::SurfaceHandler &surfaceHandler) {
|
|
201
|
+
surfaceHandler.constraintLayout(layoutConstraints, layoutContext);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
void FabricUIManager::visit(
|
|
206
|
+
facebook::react::SurfaceId surfaceId,
|
|
207
|
+
const std::function<void(const facebook::react::SurfaceHandler &surfaceHandler)> &callback) const noexcept {
|
|
208
|
+
std::shared_lock lock(m_handlerMutex);
|
|
209
|
+
|
|
210
|
+
auto iterator = m_handlerRegistry.find(surfaceId);
|
|
211
|
+
|
|
212
|
+
if (iterator == m_handlerRegistry.end()) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
callback(iterator->second);
|
|
175
217
|
}
|
|
176
218
|
|
|
177
219
|
winrt::Microsoft::ReactNative::ReactNotificationId<facebook::react::SurfaceId>
|