react-native-windows 0.76.10 → 0.76.12

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.
Files changed (58) hide show
  1. package/Directory.Build.props +2 -2
  2. package/Folly/TEMP_UntilFollyUpdate/json.cpp +4 -0
  3. package/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.cpp +23 -15
  4. package/Folly/TEMP_UntilFollyUpdate/lang/ToAscii.h +5 -5
  5. package/Folly/cgmanifest.json +1 -1
  6. package/Libraries/Components/Button.windows.js +3 -0
  7. package/Libraries/Components/ScrollView/ScrollView.windows.js +1959 -0
  8. package/Libraries/Components/View/View.windows.js +107 -56
  9. package/Libraries/Image/Image.windows.js +42 -21
  10. package/Libraries/Text/Text.d.ts +16 -1
  11. package/Microsoft.ReactNative/CompositionComponentView.idl +0 -5
  12. package/Microsoft.ReactNative/CompositionSwitcher.idl +4 -0
  13. package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp +32 -0
  14. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +159 -4
  15. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +11 -4
  16. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +0 -4
  17. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +22 -17
  18. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +1 -27
  19. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +0 -2
  20. package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +36 -11
  21. package/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h +3 -0
  22. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +50 -125
  23. package/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +9 -6
  24. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +31 -12
  25. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +6 -1
  26. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +2 -2
  27. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +145 -19
  28. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +13 -0
  29. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentDescriptor.h +0 -2
  30. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +134 -11
  31. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +6 -0
  32. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputEventEmitter.cpp +31 -0
  33. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputEventEmitter.h +14 -1
  34. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.cpp +6 -2
  35. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputProps.h +4 -1
  36. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.cpp +127 -109
  37. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.h +28 -25
  38. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.cpp +8 -18
  39. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.h +12 -35
  40. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +53 -11
  41. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +10 -2
  42. package/Microsoft.ReactNative/Fabric/ImageRequestParams.cpp +26 -0
  43. package/Microsoft.ReactNative/Fabric/WindowsImageManager.cpp +38 -8
  44. package/Microsoft.ReactNative/Fabric/WindowsImageManager.h +3 -1
  45. package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.cpp +206 -41
  46. package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.h +14 -0
  47. package/Microsoft.ReactNative/Modules/Animated/AnimationDriver.cpp +2 -1
  48. package/Microsoft.ReactNative/ReactNativeIsland.idl +3 -0
  49. package/Microsoft.ReactNative/Utils/ImageUtils.h +1 -0
  50. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  51. package/PropertySheets/NuGet.LockFile.props +1 -1
  52. package/PropertySheets/WebView2.props +1 -1
  53. package/PropertySheets/WinUI.props +1 -1
  54. package/Shared/Networking/WinRTWebSocketResource.cpp +82 -96
  55. package/Shared/Networking/WinRTWebSocketResource.h +91 -7
  56. package/Shared/Shared.vcxitems +3 -1
  57. package/Shared/Shared.vcxitems.filters +1 -0
  58. 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, {false})),
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{false};
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/debug/react_native_assert.h>
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::setContextContainer(ContextContainer *contextContainer) {
19
+ void WindowsTextInputShadowNode::setTextLayoutManager(std::shared_ptr<const TextLayoutManager> textLayoutManager) {
22
20
  ensureUnsealed();
23
- m_contextContainer = contextContainer;
21
+ textLayoutManager_ = std::move(textLayoutManager);
24
22
  }
25
23
 
26
- AttributedString WindowsTextInputShadowNode::getAttributedString(const LayoutContext &layoutContext) const {
27
- // Use BaseTextShadowNode to get attributed string from children
28
-
29
- auto childTextAttributes = TextAttributes::defaultTextAttributes();
30
- childTextAttributes.fontSizeMultiplier = layoutContext.fontSizeMultiplier;
31
-
32
- childTextAttributes.apply(getConcreteProps().textAttributes);
33
- // Don't propagate the background color of the TextInput onto the attributed
34
- // string. Android tries to render shadow of the background alongside the
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
- auto attributedString = AttributedString{};
39
- auto attachments = BaseTextShadowNode::Attachments{};
40
- BaseTextShadowNode::buildAttributedString(childTextAttributes, *this, attributedString, attachments);
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
- return attributedString;
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
- return textAttributedString;
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::setTextLayoutManager(SharedTextLayoutManager textLayoutManager) {
92
- ensureUnsealed();
93
- m_textLayoutManager = std::move(textLayoutManager);
64
+ void WindowsTextInputShadowNode::layout(LayoutContext layoutContext) {
65
+ updateStateIfNeeded(layoutContext);
66
+ ConcreteViewShadowNode::layout(layoutContext);
94
67
  }
95
68
 
96
- AttributedString WindowsTextInputShadowNode::getMostRecentAttributedString(const LayoutContext &layoutContext) const {
97
- const auto &state = getStateData();
98
-
99
- auto reactTreeAttributedString = getAttributedString(layoutContext);
100
-
101
- // Sometimes the treeAttributedString will only differ from the state
102
- // not by inherent properties (string or prop attributes), but by the frame of
103
- // the parent which has changed Thus, we can't directly compare the entire
104
- // AttributedString
105
- bool treeAttributedStringChanged =
106
- !state.reactTreeAttributedString.compareTextAttributesWithoutFrame(reactTreeAttributedString);
107
-
108
- return (!treeAttributedStringChanged ? state.attributedString : reactTreeAttributedString);
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
- #pragma mark - LayoutableShadowNode
130
+ AttributedString WindowsTextInputShadowNode::getAttributedString(const LayoutContext &layoutContext) const {
131
+ // Use BaseTextShadowNode to get attributed string from children
160
132
 
161
- Size WindowsTextInputShadowNode::measureContent(
162
- const LayoutContext &layoutContext,
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
- // Layout is called right after measure.
174
- // Measure is marked as `const`, and `layout` is not; so State can be updated
175
- // during layout, but not during `measure`. If State is out-of-date in layout,
176
- // it's too late: measure will have already operated on old State. Thus, we
177
- // use the same value here that we *will* use in layout to update the state.
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
- if (attributedString.isEmpty()) {
181
- attributedString = getPlaceholderAttributedString(layoutContext);
182
- }
142
+ auto attributedString = AttributedString{};
143
+ auto attachments = BaseTextShadowNode::Attachments{};
144
+ BaseTextShadowNode::buildAttributedString(childTextAttributes, *this, attributedString, attachments);
183
145
 
184
- if (attributedString.isEmpty() && getStateData().mostRecentEventCount != 0) {
185
- return {0, 0};
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
- TextLayoutContext textLayoutContext;
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
- void WindowsTextInputShadowNode::layout(LayoutContext layoutContext) {
200
- updateStateIfNeeded(layoutContext);
201
- ConcreteViewShadowNode::layout(layoutContext);
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
- * `ParagraphShadowNode` uses the manager to measure text content
51
- * and construct `ParagraphState` objects.
43
+ * `TextInputShadowNode` uses the manager to measure text content
44
+ * and construct `TextInputState` objects.
52
45
  */
53
- void setTextLayoutManager(SharedTextLayoutManager textLayoutManager);
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
- private:
61
- ContextContainer *m_contextContainer{};
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
- * Get the most up-to-date attributed string for measurement and State.
59
+ std::shared_ptr<const TextLayoutManager> textLayoutManager_;
60
+
61
+ /*
62
+ * Determines the constraints to use while measure the underlying text
65
63
  */
66
- AttributedString getMostRecentAttributedString(const LayoutContext &layoutContext) const;
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
- * Cached attributed string that represents the content of the subtree started
78
- * from the node.
74
+ * Returns a `AttributedString` which represents text content of the node.
79
75
  */
80
- mutable std::optional<AttributedString> m_cachedAttributedString{};
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
- #include <react/renderer/components/text/conversions.h>
8
- #include <react/renderer/debug/debugStringConvertibleUtils.h>
9
- #include <react/renderer/mapbuffer/MapBuffer.h>
10
- #include <react/renderer/mapbuffer/MapBufferBuilder.h>
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
- int64_t mostRecentEventCount,
18
- AttributedString attributedString,
15
+ AttributedStringBox attributedStringBox,
19
16
  AttributedString reactTreeAttributedString,
20
17
  ParagraphAttributes paragraphAttributes,
21
- double defaultThemePaddingStart,
22
- double defaultThemePaddingEnd,
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
- defaultThemePaddingStart(defaultThemePaddingStart),
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 <folly/dynamic.h>
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 <WindowsTextInput> component.
13
+ * State for <TextInput> component.
17
14
  */
18
15
  class WindowsTextInputState final {
19
16
  public:
20
- int64_t mostRecentEventCount{0};
17
+ WindowsTextInputState() = default;
21
18
 
22
- /**
23
- * Stores an opaque cache ID used on the Java side to refer to a specific
24
- * AttributedString for measurement purposes only.
25
- */
26
- int64_t cachedAttributedStringId{0};
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 represented as an `AttributedString`.
30
- * Only set if changed from the React tree's perspective.
26
+ * All content of <TextInput> component.
31
27
  */
32
- AttributedString attributedString{};
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
- m_surfaceManager->startSurface(
147
- surfaceId,
148
- moduleName,
149
- initialProps,
150
- layoutConstraints,
151
- layoutContext // layout context
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
- m_surfaceManager->stopSurface(surfaceId);
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
- return m_surfaceManager->measureSurface(surfaceId, layoutConstraints, layoutContext);
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
- m_surfaceManager->constraintSurfaceLayout(surfaceId, layoutConstraints, layoutContext);
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>