Skip to content

Commit 9302f25

Browse files
authored
Merge branch 'main' into revert
2 parents ba289bd + 0700dd5 commit 9302f25

File tree

7 files changed

+197
-63
lines changed

7 files changed

+197
-63
lines changed

packages/react-dom-bindings/src/server/ReactDOMServerFormatConfig.js

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3926,48 +3926,51 @@ function writeStyleResourceAttributeInJS(
39263926
return;
39273927

39283928
// Attribute renames
3929-
case 'className':
3929+
case 'className': {
39303930
attributeName = 'class';
3931+
if (__DEV__) {
3932+
checkAttributeStringCoercion(value, attributeName);
3933+
}
3934+
attributeValue = '' + (value: any);
39313935
break;
3932-
3936+
}
39333937
// Booleans
3934-
case 'hidden':
3938+
case 'hidden': {
39353939
if (value === false) {
39363940
return;
39373941
}
39383942
attributeValue = '';
39393943
break;
3940-
3944+
}
39413945
// Santized URLs
39423946
case 'src':
39433947
case 'href': {
3948+
value = sanitizeURL(value);
39443949
if (__DEV__) {
39453950
checkAttributeStringCoercion(value, attributeName);
39463951
}
3947-
value = sanitizeURL(value);
3952+
attributeValue = '' + (value: any);
39483953
break;
39493954
}
39503955
default: {
3956+
if (
3957+
// unrecognized event handlers are not SSR'd and we (apparently)
3958+
// use on* as hueristic for these handler props
3959+
name.length > 2 &&
3960+
(name[0] === 'o' || name[0] === 'O') &&
3961+
(name[1] === 'n' || name[1] === 'N')
3962+
) {
3963+
return;
3964+
}
39513965
if (!isAttributeNameSafe(name)) {
39523966
return;
39533967
}
3968+
if (__DEV__) {
3969+
checkAttributeStringCoercion(value, attributeName);
3970+
}
3971+
attributeValue = '' + (value: any);
39543972
}
39553973
}
3956-
3957-
if (
3958-
// shouldIgnoreAttribute
3959-
// We have already filtered out null/undefined and reserved words.
3960-
name.length > 2 &&
3961-
(name[0] === 'o' || name[0] === 'O') &&
3962-
(name[1] === 'n' || name[1] === 'N')
3963-
) {
3964-
return;
3965-
}
3966-
3967-
if (__DEV__) {
3968-
checkAttributeStringCoercion(value, attributeName);
3969-
}
3970-
attributeValue = '' + (value: any);
39713974
writeChunk(destination, arrayInterstitial);
39723975
writeChunk(
39733976
destination,
@@ -4119,48 +4122,53 @@ function writeStyleResourceAttributeInAttr(
41194122
return;
41204123

41214124
// Attribute renames
4122-
case 'className':
4125+
case 'className': {
41234126
attributeName = 'class';
4127+
if (__DEV__) {
4128+
checkAttributeStringCoercion(value, attributeName);
4129+
}
4130+
attributeValue = '' + (value: any);
41244131
break;
4132+
}
41254133

41264134
// Booleans
4127-
case 'hidden':
4135+
case 'hidden': {
41284136
if (value === false) {
41294137
return;
41304138
}
41314139
attributeValue = '';
41324140
break;
4141+
}
41334142

41344143
// Santized URLs
41354144
case 'src':
41364145
case 'href': {
4146+
value = sanitizeURL(value);
41374147
if (__DEV__) {
41384148
checkAttributeStringCoercion(value, attributeName);
41394149
}
4140-
value = sanitizeURL(value);
4150+
attributeValue = '' + (value: any);
41414151
break;
41424152
}
41434153
default: {
4154+
if (
4155+
// unrecognized event handlers are not SSR'd and we (apparently)
4156+
// use on* as hueristic for these handler props
4157+
name.length > 2 &&
4158+
(name[0] === 'o' || name[0] === 'O') &&
4159+
(name[1] === 'n' || name[1] === 'N')
4160+
) {
4161+
return;
4162+
}
41444163
if (!isAttributeNameSafe(name)) {
41454164
return;
41464165
}
4166+
if (__DEV__) {
4167+
checkAttributeStringCoercion(value, attributeName);
4168+
}
4169+
attributeValue = '' + (value: any);
41474170
}
41484171
}
4149-
4150-
if (
4151-
// shouldIgnoreAttribute
4152-
// We have already filtered out null/undefined and reserved words.
4153-
name.length > 2 &&
4154-
(name[0] === 'o' || name[0] === 'O') &&
4155-
(name[1] === 'n' || name[1] === 'N')
4156-
) {
4157-
return;
4158-
}
4159-
4160-
if (__DEV__) {
4161-
checkAttributeStringCoercion(value, attributeName);
4162-
}
4163-
attributeValue = '' + (value: any);
41644172
writeChunk(destination, arrayInterstitial);
41654173
writeChunk(
41664174
destination,

packages/react-native-renderer/src/ReactFabricHostConfig.js

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,16 @@ import {
1414
DefaultEventPriority,
1515
DiscreteEventPriority,
1616
} from 'react-reconciler/src/ReactEventPriorities';
17+
import {HostText} from 'react-reconciler/src/ReactWorkTags';
1718

1819
// Modules provided by RN:
1920
import {
2021
ReactNativeViewConfigRegistry,
2122
deepFreezeAndThrowOnMutationInDev,
2223
createPublicInstance,
24+
createPublicTextInstance,
2325
type PublicInstance as ReactNativePublicInstance,
26+
type PublicTextInstance,
2427
} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
2528

2629
const {
@@ -47,23 +50,33 @@ const {get: getViewConfigForType} = ReactNativeViewConfigRegistry;
4750
// This means that they never overlap.
4851
let nextReactTag = 2;
4952

53+
type InternalInstanceHandle = Object;
5054
type Node = Object;
5155
export type Type = string;
5256
export type Props = Object;
5357
export type Instance = {
5458
// Reference to the shadow node.
5559
node: Node,
60+
// This object is shared by all the clones of the instance.
61+
// We use it to access their shared public instance (exposed through refs)
62+
// and to access its committed state for events, etc.
5663
canonical: {
5764
nativeTag: number,
5865
viewConfig: ViewConfig,
5966
currentProps: Props,
6067
// Reference to the React handle (the fiber)
61-
internalInstanceHandle: Object,
68+
internalInstanceHandle: InternalInstanceHandle,
6269
// Exposed through refs.
6370
publicInstance: PublicInstance,
6471
},
6572
};
66-
export type TextInstance = {node: Node, ...};
73+
export type TextInstance = {
74+
// Reference to the shadow node.
75+
node: Node,
76+
// Text instances are never cloned, so we don't need to keep a "canonical"
77+
// reference to make sure all clones of the instance point to the same values.
78+
publicInstance?: PublicTextInstance,
79+
};
6780
export type HydratableInstance = Instance | TextInstance;
6881
export type PublicInstance = ReactNativePublicInstance;
6982
export type Container = number;
@@ -115,7 +128,7 @@ export function createInstance(
115128
props: Props,
116129
rootContainerInstance: Container,
117130
hostContext: HostContext,
118-
internalInstanceHandle: Object,
131+
internalInstanceHandle: InternalInstanceHandle,
119132
): Instance {
120133
const tag = nextReactTag;
121134
nextReactTag += 2;
@@ -162,7 +175,7 @@ export function createTextInstance(
162175
text: string,
163176
rootContainerInstance: Container,
164177
hostContext: HostContext,
165-
internalInstanceHandle: Object,
178+
internalInstanceHandle: InternalInstanceHandle,
166179
): TextInstance {
167180
if (__DEV__) {
168181
if (!hostContext.isInAParentText) {
@@ -239,9 +252,26 @@ export function getPublicInstance(instance: Instance): null | PublicInstance {
239252
return null;
240253
}
241254

255+
function getPublicTextInstance(
256+
textInstance: TextInstance,
257+
internalInstanceHandle: InternalInstanceHandle,
258+
): PublicTextInstance {
259+
if (textInstance.publicInstance == null) {
260+
textInstance.publicInstance = createPublicTextInstance(
261+
internalInstanceHandle,
262+
);
263+
}
264+
return textInstance.publicInstance;
265+
}
266+
242267
export function getPublicInstanceFromInternalInstanceHandle(
243-
internalInstanceHandle: Object,
244-
): null | PublicInstance {
268+
internalInstanceHandle: InternalInstanceHandle,
269+
): null | PublicInstance | PublicTextInstance {
270+
if (internalInstanceHandle.tag === HostText) {
271+
const textInstance: TextInstance = internalInstanceHandle.stateNode;
272+
return getPublicTextInstance(textInstance, internalInstanceHandle);
273+
}
274+
245275
const instance: Instance = internalInstanceHandle.stateNode;
246276
return getPublicInstance(instance);
247277
}
@@ -321,7 +351,7 @@ export function cloneInstance(
321351
type: string,
322352
oldProps: Props,
323353
newProps: Props,
324-
internalInstanceHandle: Object,
354+
internalInstanceHandle: InternalInstanceHandle,
325355
keepChildren: boolean,
326356
recyclableInstance: null | Instance,
327357
): Instance {
@@ -350,7 +380,7 @@ export function cloneHiddenInstance(
350380
instance: Instance,
351381
type: string,
352382
props: Props,
353-
internalInstanceHandle: Object,
383+
internalInstanceHandle: InternalInstanceHandle,
354384
): Instance {
355385
const viewConfig = instance.canonical.viewConfig;
356386
const node = instance.node;
@@ -367,7 +397,7 @@ export function cloneHiddenInstance(
367397
export function cloneHiddenTextInstance(
368398
instance: Instance,
369399
text: string,
370-
internalInstanceHandle: Object,
400+
internalInstanceHandle: InternalInstanceHandle,
371401
): TextInstance {
372402
throw new Error('Not yet implemented.');
373403
}
@@ -399,7 +429,9 @@ export function getInstanceFromNode(node: any): empty {
399429
throw new Error('Not yet implemented.');
400430
}
401431

402-
export function beforeActiveInstanceBlur(internalInstanceHandle: Object) {
432+
export function beforeActiveInstanceBlur(
433+
internalInstanceHandle: InternalInstanceHandle,
434+
) {
403435
// noop
404436
}
405437

packages/react-native-renderer/src/ReactNativeTypes.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ export type ReactNativeType = {
215215
export opaque type Node = mixed;
216216
export opaque type InternalInstanceHandle = mixed;
217217
type PublicInstance = mixed;
218+
type PublicTextInstance = mixed;
218219

219220
export type ReactFabricType = {
220221
findHostInstance_DEPRECATED<TElementType: ElementType>(
@@ -244,7 +245,7 @@ export type ReactFabricType = {
244245
): ?Node,
245246
getPublicInstanceFromInternalInstanceHandle(
246247
internalInstanceHandle: InternalInstanceHandle,
247-
): PublicInstance,
248+
): PublicInstance | PublicTextInstance,
248249
...
249250
};
250251

packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/ReactNativePrivateInterface.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
export opaque type PublicInstance = mixed;
11+
export opaque type PublicTextInstance = mixed;
1112

1213
module.exports = {
1314
get BatchedBridge() {
@@ -55,4 +56,7 @@ module.exports = {
5556
get createPublicInstance() {
5657
return require('./createPublicInstance').default;
5758
},
59+
get createPublicTextInstance() {
60+
return require('./createPublicTextInstance').default;
61+
},
5862
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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
8+
*/
9+
10+
import type {PublicInstance} from './ReactNativePrivateInterface';
11+
12+
export default function createPublicTextInstance(
13+
internalInstanceHandle: mixed,
14+
): PublicInstance {
15+
return {
16+
__internalInstanceHandle: internalInstanceHandle,
17+
};
18+
}

0 commit comments

Comments
 (0)