react-native-windows 0.77.0-preview.1 → 0.77.0-preview.3

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.
@@ -113,7 +113,7 @@ export function createCompositeKeyForProps(
113
113
  const key = keys[ii];
114
114
  const value = props[key];
115
115
 
116
- if (allowlist == null || Object.hasOwn(allowlist, key)) {
116
+ if (allowlist == null || hasOwn(allowlist, key)) {
117
117
  let compositeKeyComponent;
118
118
  if (key === 'style') {
119
119
  // $FlowFixMe[incompatible-call] - `style` is a valid argument.
@@ -205,7 +205,7 @@ function createCompositeKeyForObject(
205
205
  for (let ii = 0, length = keys.length; ii < length; ii++) {
206
206
  const key = keys[ii];
207
207
 
208
- if (allowlist == null || Object.hasOwn(allowlist, key)) {
208
+ if (allowlist == null || hasOwn(allowlist, key)) {
209
209
  const value = object[key];
210
210
 
211
211
  let compositeKeyComponent;
@@ -250,7 +250,7 @@ export function areCompositeKeysEqual(
250
250
  }
251
251
  for (let ii = 0; ii < length; ii++) {
252
252
  const key = keys[ii];
253
- if (!Object.hasOwn(next, key)) {
253
+ if (!hasOwn(next, key)) {
254
254
  return false;
255
255
  }
256
256
  const prevComponent = prev[key];
@@ -336,7 +336,7 @@ function areCompositeKeyComponentsEqual(
336
336
  for (let ii = 0; ii < length; ii++) {
337
337
  const key = keys[ii];
338
338
  if (
339
- !Object.hasOwn(nullthrows(next), key) ||
339
+ !hasOwn(nullthrows(next), key) ||
340
340
  !areCompositeKeyComponentsEqual(prev[key], next[key])
341
341
  ) {
342
342
  return false;
@@ -346,3 +346,11 @@ function areCompositeKeyComponentsEqual(
346
346
  }
347
347
  return false;
348
348
  }
349
+
350
+ // Supported versions of JSC do not implement the newer Object.hasOwn. Remove
351
+ // this shim when they do.
352
+ // $FlowIgnore[method-unbinding]
353
+ const _hasOwnProp = Object.prototype.hasOwnProperty;
354
+ const hasOwn: (obj: $ReadOnly<{...}>, prop: string) => boolean =
355
+ // $FlowIgnore[method-unbinding]
356
+ Object.hasOwn ?? ((obj, prop) => _hasOwnProp.call(obj, prop));
@@ -1,122 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow strict-local
8
- * @format
9
- */
10
-
11
- import type {AnimatedPropsAllowlist} from './nodes/AnimatedProps';
12
-
13
- import * as ReactNativeFeatureFlags from '../../src/private/featureflags/ReactNativeFeatureFlags';
14
-
15
- /**
16
- * Styles allowed by the native animated implementation.
17
- *
18
- * In general native animated implementation should support any numeric or color property that
19
- * doesn't need to be updated through the shadow view hierarchy (all non-layout properties).
20
- */
21
- const SUPPORTED_COLOR_STYLES: {[string]: true} = {
22
- backgroundColor: true,
23
- borderBottomColor: true,
24
- borderColor: true,
25
- borderEndColor: true,
26
- borderLeftColor: true,
27
- borderRightColor: true,
28
- borderStartColor: true,
29
- borderTopColor: true,
30
- color: true,
31
- tintColor: true,
32
- };
33
-
34
- const SUPPORTED_STYLES: {[string]: true} = {
35
- ...SUPPORTED_COLOR_STYLES,
36
- borderBottomEndRadius: true,
37
- borderBottomLeftRadius: true,
38
- borderBottomRightRadius: true,
39
- borderBottomStartRadius: true,
40
- borderEndEndRadius: true,
41
- borderEndStartRadius: true,
42
- borderRadius: true,
43
- borderTopEndRadius: true,
44
- borderTopLeftRadius: true,
45
- borderTopRightRadius: true,
46
- borderTopStartRadius: true,
47
- borderStartEndRadius: true,
48
- borderStartStartRadius: true,
49
- elevation: true,
50
- opacity: true,
51
- transform: true,
52
- zIndex: true,
53
- /* ios styles */
54
- shadowOpacity: true,
55
- shadowRadius: true,
56
- /* legacy android transform properties */
57
- scaleX: true,
58
- scaleY: true,
59
- translateX: true,
60
- translateY: true,
61
- };
62
-
63
- const SUPPORTED_TRANSFORMS: {[string]: true} = {
64
- translateX: true,
65
- translateY: true,
66
- scale: true,
67
- scaleX: true,
68
- scaleY: true,
69
- rotate: true,
70
- rotateX: true,
71
- rotateY: true,
72
- rotateZ: true,
73
- perspective: true,
74
- skewX: true,
75
- skewY: true,
76
- ...(ReactNativeFeatureFlags.shouldUseAnimatedObjectForTransform()
77
- ? {matrix: true}
78
- : {}),
79
- };
80
-
81
- const SUPPORTED_INTERPOLATION_PARAMS: {[string]: true} = {
82
- inputRange: true,
83
- outputRange: true,
84
- extrapolate: true,
85
- extrapolateRight: true,
86
- extrapolateLeft: true,
87
- };
88
-
89
- /**
90
- * Default allowlist for component props that support native animated values.
91
- */
92
- export default {
93
- style: SUPPORTED_STYLES,
94
- } as AnimatedPropsAllowlist;
95
-
96
- export function allowInterpolationParam(param: string): void {
97
- SUPPORTED_INTERPOLATION_PARAMS[param] = true;
98
- }
99
-
100
- export function allowStyleProp(prop: string): void {
101
- SUPPORTED_STYLES[prop] = true;
102
- }
103
-
104
- export function allowTransformProp(prop: string): void {
105
- SUPPORTED_TRANSFORMS[prop] = true;
106
- }
107
-
108
- export function isSupportedColorStyleProp(prop: string): boolean {
109
- return SUPPORTED_COLOR_STYLES.hasOwnProperty(prop);
110
- }
111
-
112
- export function isSupportedInterpolationParam(param: string): boolean {
113
- return SUPPORTED_INTERPOLATION_PARAMS.hasOwnProperty(param);
114
- }
115
-
116
- export function isSupportedStyleProp(prop: string): boolean {
117
- return SUPPORTED_STYLES.hasOwnProperty(prop);
118
- }
119
-
120
- export function isSupportedTransformProp(prop: string): boolean {
121
- return SUPPORTED_TRANSFORMS.hasOwnProperty(prop);
122
- }
@@ -1,281 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- * @format
9
- */
10
-
11
- import type {PlatformConfig} from '../AnimatedPlatformConfig';
12
- import type {AnimatedStyleAllowlist} from './AnimatedStyle';
13
-
14
- import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper';
15
- import {findNodeHandle} from '../../ReactNative/RendererProxy';
16
- import {AnimatedEvent} from '../AnimatedEvent';
17
- import AnimatedNode from './AnimatedNode';
18
- import AnimatedObject from './AnimatedObject';
19
- import AnimatedStyle from './AnimatedStyle';
20
- import invariant from 'invariant';
21
-
22
- export type AnimatedPropsAllowlist = $ReadOnly<{
23
- style?: ?AnimatedStyleAllowlist,
24
- [string]: true,
25
- }>;
26
-
27
- function createAnimatedProps(
28
- inputProps: {[string]: mixed},
29
- allowlist: ?AnimatedPropsAllowlist,
30
- ): [$ReadOnlyArray<string>, $ReadOnlyArray<AnimatedNode>, {[string]: mixed}] {
31
- const nodeKeys: Array<string> = [];
32
- const nodes: Array<AnimatedNode> = [];
33
- const props: {[string]: mixed} = {};
34
-
35
- const keys = Object.keys(inputProps);
36
- for (let ii = 0, length = keys.length; ii < length; ii++) {
37
- const key = keys[ii];
38
- const value = inputProps[key];
39
-
40
- if (allowlist == null || hasOwn(allowlist, key)) {
41
- let node;
42
- if (key === 'style') {
43
- node = AnimatedStyle.from(value, allowlist?.style);
44
- } else if (value instanceof AnimatedNode) {
45
- node = value;
46
- } else {
47
- node = AnimatedObject.from(value);
48
- }
49
- if (node == null) {
50
- props[key] = value;
51
- } else {
52
- nodeKeys.push(key);
53
- nodes.push(node);
54
- props[key] = node;
55
- }
56
- } else {
57
- if (__DEV__) {
58
- // WARNING: This is a potentially expensive check that we should only
59
- // do in development. Without this check in development, it might be
60
- // difficult to identify which props need to be allowlisted.
61
- if (AnimatedObject.from(inputProps[key]) != null) {
62
- console.error(
63
- `AnimatedProps: ${key} is not allowlisted for animation, but it ` +
64
- 'contains AnimatedNode values; props allowing animation: ',
65
- allowlist,
66
- );
67
- }
68
- }
69
- props[key] = value;
70
- }
71
- }
72
-
73
- return [nodeKeys, nodes, props];
74
- }
75
-
76
- export default class AnimatedProps extends AnimatedNode {
77
- #animatedView: any = null;
78
- #callback: () => void;
79
- #nodeKeys: $ReadOnlyArray<string>;
80
- #nodes: $ReadOnlyArray<AnimatedNode>;
81
- #props: {[string]: mixed};
82
-
83
- constructor(
84
- inputProps: {[string]: mixed},
85
- callback: () => void,
86
- allowlist?: ?AnimatedPropsAllowlist,
87
- ) {
88
- super();
89
- const [nodeKeys, nodes, props] = createAnimatedProps(inputProps, allowlist);
90
- this.#nodeKeys = nodeKeys;
91
- this.#nodes = nodes;
92
- this.#props = props;
93
- this.#callback = callback;
94
- }
95
-
96
- __getValue(): Object {
97
- const props: {[string]: mixed} = {};
98
-
99
- const keys = Object.keys(this.#props);
100
- for (let ii = 0, length = keys.length; ii < length; ii++) {
101
- const key = keys[ii];
102
- const value = this.#props[key];
103
-
104
- if (value instanceof AnimatedNode) {
105
- props[key] = value.__getValue();
106
- } else if (value instanceof AnimatedEvent) {
107
- props[key] = value.__getHandler();
108
- } else {
109
- props[key] = value;
110
- }
111
- }
112
-
113
- return props;
114
- }
115
-
116
- /**
117
- * Creates a new `props` object that contains the same props as the supplied
118
- * `staticProps` object, except with animated nodes for any props that were
119
- * created by this `AnimatedProps` instance.
120
- */
121
- __getValueWithStaticProps(staticProps: Object): Object {
122
- const props: {[string]: mixed} = {...staticProps};
123
-
124
- const keys = Object.keys(staticProps);
125
- for (let ii = 0, length = keys.length; ii < length; ii++) {
126
- const key = keys[ii];
127
- const maybeNode = this.#props[key];
128
-
129
- if (key === 'style' && maybeNode instanceof AnimatedStyle) {
130
- props[key] = maybeNode.__getValueWithStaticStyle(staticProps.style);
131
- } else if (maybeNode instanceof AnimatedNode) {
132
- props[key] = maybeNode.__getValue();
133
- } else if (maybeNode instanceof AnimatedEvent) {
134
- props[key] = maybeNode.__getHandler();
135
- }
136
- }
137
-
138
- return props;
139
- }
140
-
141
- __getAnimatedValue(): Object {
142
- const props: {[string]: mixed} = {};
143
-
144
- const nodeKeys = this.#nodeKeys;
145
- const nodes = this.#nodes;
146
- for (let ii = 0, length = nodes.length; ii < length; ii++) {
147
- const key = nodeKeys[ii];
148
- const node = nodes[ii];
149
- props[key] = node.__getAnimatedValue();
150
- }
151
-
152
- return props;
153
- }
154
-
155
- __attach(): void {
156
- const nodes = this.#nodes;
157
- for (let ii = 0, length = nodes.length; ii < length; ii++) {
158
- const node = nodes[ii];
159
- node.__addChild(this);
160
- }
161
- }
162
-
163
- __detach(): void {
164
- if (this.__isNative && this.#animatedView) {
165
- this.__disconnectAnimatedView();
166
- }
167
- this.#animatedView = null;
168
-
169
- const nodes = this.#nodes;
170
- for (let ii = 0, length = nodes.length; ii < length; ii++) {
171
- const node = nodes[ii];
172
- node.__removeChild(this);
173
- }
174
-
175
- super.__detach();
176
- }
177
-
178
- update(): void {
179
- this.#callback();
180
- }
181
-
182
- __makeNative(platformConfig: ?PlatformConfig): void {
183
- const nodes = this.#nodes;
184
- for (let ii = 0, length = nodes.length; ii < length; ii++) {
185
- const node = nodes[ii];
186
- node.__makeNative(platformConfig);
187
- }
188
-
189
- if (!this.__isNative) {
190
- this.__isNative = true;
191
-
192
- // Since this does not call the super.__makeNative, we need to store the
193
- // supplied platformConfig here, before calling __connectAnimatedView
194
- // where it will be needed to traverse the graph of attached values.
195
- super.__setPlatformConfig(platformConfig);
196
-
197
- if (this.#animatedView) {
198
- this.__connectAnimatedView();
199
- }
200
- }
201
- }
202
-
203
- setNativeView(animatedView: any): void {
204
- if (this.#animatedView === animatedView) {
205
- return;
206
- }
207
- this.#animatedView = animatedView;
208
- if (this.__isNative) {
209
- this.__connectAnimatedView();
210
- }
211
- }
212
-
213
- __connectAnimatedView(): void {
214
- invariant(this.__isNative, 'Expected node to be marked as "native"');
215
- let nativeViewTag: ?number = findNodeHandle(this.#animatedView);
216
- if (nativeViewTag == null) {
217
- if (process.env.NODE_ENV === 'test') {
218
- nativeViewTag = -1;
219
- } else {
220
- throw new Error('Unable to locate attached view in the native tree');
221
- }
222
- }
223
- NativeAnimatedHelper.API.connectAnimatedNodeToView(
224
- this.__getNativeTag(),
225
- nativeViewTag,
226
- );
227
- }
228
-
229
- __disconnectAnimatedView(): void {
230
- invariant(this.__isNative, 'Expected node to be marked as "native"');
231
- let nativeViewTag: ?number = findNodeHandle(this.#animatedView);
232
- if (nativeViewTag == null) {
233
- if (process.env.NODE_ENV === 'test') {
234
- nativeViewTag = -1;
235
- } else {
236
- throw new Error('Unable to locate attached view in the native tree');
237
- }
238
- }
239
- NativeAnimatedHelper.API.disconnectAnimatedNodeFromView(
240
- this.__getNativeTag(),
241
- nativeViewTag,
242
- );
243
- }
244
-
245
- __restoreDefaultValues(): void {
246
- // When using the native driver, view properties need to be restored to
247
- // their default values manually since react no longer tracks them. This
248
- // is needed to handle cases where a prop driven by native animated is removed
249
- // after having been changed natively by an animation.
250
- if (this.__isNative) {
251
- NativeAnimatedHelper.API.restoreDefaultValues(this.__getNativeTag());
252
- }
253
- }
254
-
255
- __getNativeConfig(): Object {
256
- const platformConfig = this.__getPlatformConfig();
257
- const propsConfig: {[string]: number} = {};
258
-
259
- const nodeKeys = this.#nodeKeys;
260
- const nodes = this.#nodes;
261
- for (let ii = 0, length = nodes.length; ii < length; ii++) {
262
- const key = nodeKeys[ii];
263
- const node = nodes[ii];
264
- node.__makeNative(platformConfig);
265
- propsConfig[key] = node.__getNativeTag();
266
- }
267
-
268
- return {
269
- type: 'props',
270
- props: propsConfig,
271
- };
272
- }
273
- }
274
-
275
- // Supported versions of JSC do not implement the newer Object.hasOwn. Remove
276
- // this shim when they do.
277
- // $FlowIgnore[method-unbinding]
278
- const _hasOwnProp = Object.prototype.hasOwnProperty;
279
- const hasOwn: (obj: $ReadOnly<{...}>, prop: string) => boolean =
280
- // $FlowIgnore[method-unbinding]
281
- Object.hasOwn ?? ((obj, prop) => _hasOwnProp.call(obj, prop));
@@ -1,251 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @flow
8
- * @format
9
- */
10
-
11
- import type {PlatformConfig} from '../AnimatedPlatformConfig';
12
-
13
- import {validateStyles} from '../../../src/private/animated/NativeAnimatedValidation';
14
- import * as ReactNativeFeatureFlags from '../../../src/private/featureflags/ReactNativeFeatureFlags';
15
- import flattenStyle from '../../StyleSheet/flattenStyle';
16
- import Platform from '../../Utilities/Platform';
17
- import AnimatedNode from './AnimatedNode';
18
- import AnimatedObject from './AnimatedObject';
19
- import AnimatedTransform from './AnimatedTransform';
20
- import AnimatedWithChildren from './AnimatedWithChildren';
21
-
22
- export type AnimatedStyleAllowlist = $ReadOnly<{[string]: true}>;
23
-
24
- function createAnimatedStyle(
25
- inputStyle: {[string]: mixed},
26
- allowlist: ?AnimatedStyleAllowlist,
27
- keepUnanimatedValues: boolean,
28
- ): [$ReadOnlyArray<string>, $ReadOnlyArray<AnimatedNode>, {[string]: mixed}] {
29
- const nodeKeys: Array<string> = [];
30
- const nodes: Array<AnimatedNode> = [];
31
- const style: {[string]: mixed} = {};
32
-
33
- const keys = Object.keys(inputStyle);
34
- for (let ii = 0, length = keys.length; ii < length; ii++) {
35
- const key = keys[ii];
36
- const value = inputStyle[key];
37
-
38
- if (allowlist == null || hasOwn(allowlist, key)) {
39
- let node;
40
- if (value != null && key === 'transform') {
41
- node = ReactNativeFeatureFlags.shouldUseAnimatedObjectForTransform()
42
- ? AnimatedObject.from(value)
43
- : // $FlowFixMe[incompatible-call] - `value` is mixed.
44
- AnimatedTransform.from(value);
45
- } else if (value instanceof AnimatedNode) {
46
- node = value;
47
- } else {
48
- node = AnimatedObject.from(value);
49
- }
50
- if (node == null) {
51
- if (keepUnanimatedValues) {
52
- style[key] = value;
53
- }
54
- } else {
55
- nodeKeys.push(key);
56
- nodes.push(node);
57
- style[key] = node;
58
- }
59
- } else {
60
- if (__DEV__) {
61
- // WARNING: This is a potentially expensive check that we should only
62
- // do in development. Without this check in development, it might be
63
- // difficult to identify which styles need to be allowlisted.
64
- if (AnimatedObject.from(inputStyle[key]) != null) {
65
- console.error(
66
- `AnimatedStyle: ${key} is not allowlisted for animation, but it ` +
67
- 'contains AnimatedNode values; styles allowing animation: ',
68
- allowlist,
69
- );
70
- }
71
- }
72
- if (keepUnanimatedValues) {
73
- style[key] = value;
74
- }
75
- }
76
- }
77
-
78
- return [nodeKeys, nodes, style];
79
- }
80
-
81
- export default class AnimatedStyle extends AnimatedWithChildren {
82
- #inputStyle: any;
83
- #nodeKeys: $ReadOnlyArray<string>;
84
- #nodes: $ReadOnlyArray<AnimatedNode>;
85
- #style: {[string]: mixed};
86
-
87
- /**
88
- * Creates an `AnimatedStyle` if `value` contains `AnimatedNode` instances.
89
- * Otherwise, returns `null`.
90
- */
91
- static from(
92
- inputStyle: any,
93
- allowlist: ?AnimatedStyleAllowlist,
94
- ): ?AnimatedStyle {
95
- const flatStyle = flattenStyle(inputStyle);
96
- if (flatStyle == null) {
97
- return null;
98
- }
99
- const [nodeKeys, nodes, style] = createAnimatedStyle(
100
- flatStyle,
101
- allowlist,
102
- Platform.OS !== 'web',
103
- );
104
- if (nodes.length === 0) {
105
- return null;
106
- }
107
- return new AnimatedStyle(nodeKeys, nodes, style, inputStyle);
108
- }
109
-
110
- constructor(
111
- nodeKeys: $ReadOnlyArray<string>,
112
- nodes: $ReadOnlyArray<AnimatedNode>,
113
- style: {[string]: mixed},
114
- inputStyle: any,
115
- ) {
116
- super();
117
- this.#nodeKeys = nodeKeys;
118
- this.#nodes = nodes;
119
- this.#style = style;
120
- this.#inputStyle = inputStyle;
121
- }
122
-
123
- __getValue(): Object | Array<Object> {
124
- const style: {[string]: mixed} = {};
125
-
126
- const keys = Object.keys(this.#style);
127
- for (let ii = 0, length = keys.length; ii < length; ii++) {
128
- const key = keys[ii];
129
- const value = this.#style[key];
130
-
131
- if (value instanceof AnimatedNode) {
132
- style[key] = value.__getValue();
133
- } else {
134
- style[key] = value;
135
- }
136
- }
137
-
138
- /* $FlowFixMe[incompatible-type] Error found due to incomplete typing of
139
- * Platform.flow.js */
140
- return Platform.OS === 'web' ? [this.#inputStyle, style] : style;
141
- }
142
-
143
- /**
144
- * Creates a new `style` object that contains the same style properties as
145
- * the supplied `staticStyle` object, except with animated nodes for any
146
- * style properties that were created by this `AnimatedStyle` instance.
147
- */
148
- __getValueWithStaticStyle(staticStyle: Object): Object | Array<Object> {
149
- const flatStaticStyle = flattenStyle(staticStyle);
150
- const style: {[string]: mixed} =
151
- flatStaticStyle == null
152
- ? {}
153
- : flatStaticStyle === staticStyle
154
- ? // Copy the input style, since we'll mutate it below.
155
- {...flatStaticStyle}
156
- : // Reuse `flatStaticStyle` if it is a newly created object.
157
- flatStaticStyle;
158
-
159
- const keys = Object.keys(style);
160
- for (let ii = 0, length = keys.length; ii < length; ii++) {
161
- const key = keys[ii];
162
- const maybeNode = this.#style[key];
163
-
164
- if (key === 'transform' && maybeNode instanceof AnimatedTransform) {
165
- style[key] = maybeNode.__getValueWithStaticTransforms(
166
- // NOTE: This check should not be necessary, but the types are not
167
- // enforced as of this writing.
168
- Array.isArray(style[key]) ? style[key] : [],
169
- );
170
- } else if (maybeNode instanceof AnimatedObject) {
171
- style[key] = maybeNode.__getValueWithStaticObject(style[key]);
172
- } else if (maybeNode instanceof AnimatedNode) {
173
- style[key] = maybeNode.__getValue();
174
- }
175
- }
176
-
177
- /* $FlowFixMe[incompatible-type] Error found due to incomplete typing of
178
- * Platform.flow.js */
179
- return Platform.OS === 'web' ? [this.#inputStyle, style] : style;
180
- }
181
-
182
- __getAnimatedValue(): Object {
183
- const style: {[string]: mixed} = {};
184
-
185
- const nodeKeys = this.#nodeKeys;
186
- const nodes = this.#nodes;
187
- for (let ii = 0, length = nodes.length; ii < length; ii++) {
188
- const key = nodeKeys[ii];
189
- const node = nodes[ii];
190
- style[key] = node.__getAnimatedValue();
191
- }
192
-
193
- return style;
194
- }
195
-
196
- __attach(): void {
197
- const nodes = this.#nodes;
198
- for (let ii = 0, length = nodes.length; ii < length; ii++) {
199
- const node = nodes[ii];
200
- node.__addChild(this);
201
- }
202
- }
203
-
204
- __detach(): void {
205
- const nodes = this.#nodes;
206
- for (let ii = 0, length = nodes.length; ii < length; ii++) {
207
- const node = nodes[ii];
208
- node.__removeChild(this);
209
- }
210
- super.__detach();
211
- }
212
-
213
- __makeNative(platformConfig: ?PlatformConfig) {
214
- const nodes = this.#nodes;
215
- for (let ii = 0, length = nodes.length; ii < length; ii++) {
216
- const node = nodes[ii];
217
- node.__makeNative(platformConfig);
218
- }
219
- super.__makeNative(platformConfig);
220
- }
221
-
222
- __getNativeConfig(): Object {
223
- const platformConfig = this.__getPlatformConfig();
224
- const styleConfig: {[string]: ?number} = {};
225
-
226
- const nodeKeys = this.#nodeKeys;
227
- const nodes = this.#nodes;
228
- for (let ii = 0, length = nodes.length; ii < length; ii++) {
229
- const key = nodeKeys[ii];
230
- const node = nodes[ii];
231
- node.__makeNative(platformConfig);
232
- styleConfig[key] = node.__getNativeTag();
233
- }
234
-
235
- if (__DEV__) {
236
- validateStyles(styleConfig);
237
- }
238
- return {
239
- type: 'style',
240
- style: styleConfig,
241
- };
242
- }
243
- }
244
-
245
- // Supported versions of JSC do not implement the newer Object.hasOwn. Remove
246
- // this shim when they do.
247
- // $FlowIgnore[method-unbinding]
248
- const _hasOwnProp = Object.prototype.hasOwnProperty;
249
- const hasOwn: (obj: $ReadOnly<{...}>, prop: string) => boolean =
250
- // $FlowIgnore[method-unbinding]
251
- Object.hasOwn ?? ((obj, prop) => _hasOwnProp.call(obj, prop));