Skip to content

Commit

Permalink
Implement public instances for text nodes in Fabric (#26516)
Browse files Browse the repository at this point in the history
## Summary

This adds the ability to create public instances for text nodes in
Fabric. The implementation for the public instances lives in React
Native (as it does for host components after #26437). The logic here
just handles their lazy instantiation when requested via
`getPublicInstanceFromInternalInstanceHandle`, which is called by Fabric
with information coming from the shadow tree.

It's important that the creation of public instances for text nodes is
done lazily to avoid regressing memory usage when unused. Instances for
text nodes are left intact if the public instance is never accessed.

This is necessary to implement access to text nodes in React Native as
explained in
react-native-community/discussions-and-proposals#607

## How did you test this change?

Added unit tests (also fixed a test that was only testing the logic in a
mock :S).

DiffTrain build for commit 0700dd5.
  • Loading branch information
rubennorte committed Apr 4, 2023
1 parent 6b19def commit 08375e6
Show file tree
Hide file tree
Showing 14 changed files with 109 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23882,7 +23882,7 @@ function createFiberRoot(
return root;
}

var ReactVersion = "18.3.0-next-4a1cc2ddd-20230403";
var ReactVersion = "18.3.0-next-0700dd50b-20230404";

// Might add PROFILE later.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8683,7 +8683,7 @@ var devToolsConfig$jscomp$inline_1028 = {
throw Error("TestRenderer does not support findFiberByHostInstance()");
},
bundleType: 0,
version: "18.3.0-next-4a1cc2ddd-20230403",
version: "18.3.0-next-0700dd50b-20230404",
rendererPackageName: "react-test-renderer"
};
var internals$jscomp$inline_1220 = {
Expand Down Expand Up @@ -8714,7 +8714,7 @@ var internals$jscomp$inline_1220 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-4a1cc2ddd-20230403"
reconcilerVersion: "18.3.0-next-0700dd50b-20230404"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1221 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9108,7 +9108,7 @@ var devToolsConfig$jscomp$inline_1070 = {
throw Error("TestRenderer does not support findFiberByHostInstance()");
},
bundleType: 0,
version: "18.3.0-next-4a1cc2ddd-20230403",
version: "18.3.0-next-0700dd50b-20230404",
rendererPackageName: "react-test-renderer"
};
var internals$jscomp$inline_1261 = {
Expand Down Expand Up @@ -9139,7 +9139,7 @@ var internals$jscomp$inline_1261 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-4a1cc2ddd-20230403"
reconcilerVersion: "18.3.0-next-0700dd50b-20230404"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1262 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ if (
}
"use strict";

var ReactVersion = "18.3.0-next-4a1cc2ddd-20230403";
var ReactVersion = "18.3.0-next-0700dd50b-20230404";

// ATTENTION
// When adding new symbols to this file,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -639,4 +639,4 @@ exports.useSyncExternalStore = function (
);
};
exports.useTransition = useTransition;
exports.version = "18.3.0-next-4a1cc2ddd-20230403";
exports.version = "18.3.0-next-0700dd50b-20230404";
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ exports.useSyncExternalStore = function (
);
};
exports.useTransition = useTransition;
exports.version = "18.3.0-next-4a1cc2ddd-20230403";
exports.version = "18.3.0-next-0700dd50b-20230404";

/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4a1cc2ddd035f5c269e82ab6f7686e2e60d3b3ea
0700dd50bda98f5ee86f2e3adfe5e9906ed1e8e3
Original file line number Diff line number Diff line change
Expand Up @@ -4985,7 +4985,24 @@ function getPublicInstance(instance) {

return null;
}

function getPublicTextInstance(textInstance, internalInstanceHandle) {
if (textInstance.publicInstance == null) {
textInstance.publicInstance =
ReactNativePrivateInterface.createPublicTextInstance(
internalInstanceHandle
);
}

return textInstance.publicInstance;
}

function getPublicInstanceFromInternalInstanceHandle(internalInstanceHandle) {
if (internalInstanceHandle.tag === HostText) {
var textInstance = internalInstanceHandle.stateNode;
return getPublicTextInstance(textInstance, internalInstanceHandle);
}

var instance = internalInstanceHandle.stateNode;
return getPublicInstance(instance);
}
Expand Down Expand Up @@ -27158,7 +27175,7 @@ function createFiberRoot(
return root;
}

var ReactVersion = "18.3.0-next-4a1cc2ddd-20230403";
var ReactVersion = "18.3.0-next-0700dd50b-20230404";

function createPortal$1(
children,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -940,7 +940,7 @@ eventPluginOrder = Array.prototype.slice.call([
"ReactNativeBridgeEventPlugin"
]);
recomputePluginOrdering();
var injectedNamesToPlugins$jscomp$inline_243 = {
var injectedNamesToPlugins$jscomp$inline_244 = {
ResponderEventPlugin: ResponderEventPlugin,
ReactNativeBridgeEventPlugin: {
eventTypes: {},
Expand Down Expand Up @@ -986,32 +986,32 @@ var injectedNamesToPlugins$jscomp$inline_243 = {
}
}
},
isOrderingDirty$jscomp$inline_244 = !1,
pluginName$jscomp$inline_245;
for (pluginName$jscomp$inline_245 in injectedNamesToPlugins$jscomp$inline_243)
isOrderingDirty$jscomp$inline_245 = !1,
pluginName$jscomp$inline_246;
for (pluginName$jscomp$inline_246 in injectedNamesToPlugins$jscomp$inline_244)
if (
injectedNamesToPlugins$jscomp$inline_243.hasOwnProperty(
pluginName$jscomp$inline_245
injectedNamesToPlugins$jscomp$inline_244.hasOwnProperty(
pluginName$jscomp$inline_246
)
) {
var pluginModule$jscomp$inline_246 =
injectedNamesToPlugins$jscomp$inline_243[pluginName$jscomp$inline_245];
var pluginModule$jscomp$inline_247 =
injectedNamesToPlugins$jscomp$inline_244[pluginName$jscomp$inline_246];
if (
!namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_245) ||
namesToPlugins[pluginName$jscomp$inline_245] !==
pluginModule$jscomp$inline_246
!namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_246) ||
namesToPlugins[pluginName$jscomp$inline_246] !==
pluginModule$jscomp$inline_247
) {
if (namesToPlugins[pluginName$jscomp$inline_245])
if (namesToPlugins[pluginName$jscomp$inline_246])
throw Error(
"EventPluginRegistry: Cannot inject two different event plugins using the same name, `" +
(pluginName$jscomp$inline_245 + "`.")
(pluginName$jscomp$inline_246 + "`.")
);
namesToPlugins[pluginName$jscomp$inline_245] =
pluginModule$jscomp$inline_246;
isOrderingDirty$jscomp$inline_244 = !0;
namesToPlugins[pluginName$jscomp$inline_246] =
pluginModule$jscomp$inline_247;
isOrderingDirty$jscomp$inline_245 = !0;
}
}
isOrderingDirty$jscomp$inline_244 && recomputePluginOrdering();
isOrderingDirty$jscomp$inline_245 && recomputePluginOrdering();
var emptyObject$1 = {},
removedKeys = null,
removedKeyCount = 0,
Expand Down Expand Up @@ -9551,10 +9551,10 @@ batchedUpdatesImpl = function (fn, a) {
}
};
var roots = new Map(),
devToolsConfig$jscomp$inline_1048 = {
devToolsConfig$jscomp$inline_1052 = {
findFiberByHostInstance: getInstanceFromNode,
bundleType: 0,
version: "18.3.0-next-4a1cc2ddd-20230403",
version: "18.3.0-next-0700dd50b-20230404",
rendererPackageName: "react-native-renderer",
rendererConfig: {
getInspectorDataForViewTag: function () {
Expand All @@ -9569,11 +9569,11 @@ var roots = new Map(),
}.bind(null, findNodeHandle)
}
};
var internals$jscomp$inline_1293 = {
bundleType: devToolsConfig$jscomp$inline_1048.bundleType,
version: devToolsConfig$jscomp$inline_1048.version,
rendererPackageName: devToolsConfig$jscomp$inline_1048.rendererPackageName,
rendererConfig: devToolsConfig$jscomp$inline_1048.rendererConfig,
var internals$jscomp$inline_1297 = {
bundleType: devToolsConfig$jscomp$inline_1052.bundleType,
version: devToolsConfig$jscomp$inline_1052.version,
rendererPackageName: devToolsConfig$jscomp$inline_1052.rendererPackageName,
rendererConfig: devToolsConfig$jscomp$inline_1052.rendererConfig,
overrideHookState: null,
overrideHookStateDeletePath: null,
overrideHookStateRenamePath: null,
Expand All @@ -9589,26 +9589,26 @@ var internals$jscomp$inline_1293 = {
return null === fiber ? null : fiber.stateNode;
},
findFiberByHostInstance:
devToolsConfig$jscomp$inline_1048.findFiberByHostInstance ||
devToolsConfig$jscomp$inline_1052.findFiberByHostInstance ||
emptyFindFiberByHostInstance,
findHostInstancesForRefresh: null,
scheduleRefresh: null,
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-4a1cc2ddd-20230403"
reconcilerVersion: "18.3.0-next-0700dd50b-20230404"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1294 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
var hook$jscomp$inline_1298 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
if (
!hook$jscomp$inline_1294.isDisabled &&
hook$jscomp$inline_1294.supportsFiber
!hook$jscomp$inline_1298.isDisabled &&
hook$jscomp$inline_1298.supportsFiber
)
try {
(rendererID = hook$jscomp$inline_1294.inject(
internals$jscomp$inline_1293
(rendererID = hook$jscomp$inline_1298.inject(
internals$jscomp$inline_1297
)),
(injectedHook = hook$jscomp$inline_1294);
(injectedHook = hook$jscomp$inline_1298);
} catch (err) {}
}
exports.createPortal = function (children, containerTag) {
Expand Down Expand Up @@ -9687,6 +9687,15 @@ exports.getNodeFromInternalInstanceHandle = function (internalInstanceHandle) {
exports.getPublicInstanceFromInternalInstanceHandle = function (
internalInstanceHandle
) {
if (6 === internalInstanceHandle.tag) {
var textInstance = internalInstanceHandle.stateNode;
null == textInstance.publicInstance &&
(textInstance.publicInstance =
ReactNativePrivateInterface.createPublicTextInstance(
internalInstanceHandle
));
return textInstance.publicInstance;
}
return getPublicInstance(internalInstanceHandle.stateNode);
};
exports.render = function (element, containerTag, callback, concurrentRoot) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,7 @@ eventPluginOrder = Array.prototype.slice.call([
"ReactNativeBridgeEventPlugin"
]);
recomputePluginOrdering();
var injectedNamesToPlugins$jscomp$inline_259 = {
var injectedNamesToPlugins$jscomp$inline_260 = {
ResponderEventPlugin: ResponderEventPlugin,
ReactNativeBridgeEventPlugin: {
eventTypes: {},
Expand Down Expand Up @@ -997,32 +997,32 @@ var injectedNamesToPlugins$jscomp$inline_259 = {
}
}
},
isOrderingDirty$jscomp$inline_260 = !1,
pluginName$jscomp$inline_261;
for (pluginName$jscomp$inline_261 in injectedNamesToPlugins$jscomp$inline_259)
isOrderingDirty$jscomp$inline_261 = !1,
pluginName$jscomp$inline_262;
for (pluginName$jscomp$inline_262 in injectedNamesToPlugins$jscomp$inline_260)
if (
injectedNamesToPlugins$jscomp$inline_259.hasOwnProperty(
pluginName$jscomp$inline_261
injectedNamesToPlugins$jscomp$inline_260.hasOwnProperty(
pluginName$jscomp$inline_262
)
) {
var pluginModule$jscomp$inline_262 =
injectedNamesToPlugins$jscomp$inline_259[pluginName$jscomp$inline_261];
var pluginModule$jscomp$inline_263 =
injectedNamesToPlugins$jscomp$inline_260[pluginName$jscomp$inline_262];
if (
!namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_261) ||
namesToPlugins[pluginName$jscomp$inline_261] !==
pluginModule$jscomp$inline_262
!namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_262) ||
namesToPlugins[pluginName$jscomp$inline_262] !==
pluginModule$jscomp$inline_263
) {
if (namesToPlugins[pluginName$jscomp$inline_261])
if (namesToPlugins[pluginName$jscomp$inline_262])
throw Error(
"EventPluginRegistry: Cannot inject two different event plugins using the same name, `" +
(pluginName$jscomp$inline_261 + "`.")
(pluginName$jscomp$inline_262 + "`.")
);
namesToPlugins[pluginName$jscomp$inline_261] =
pluginModule$jscomp$inline_262;
isOrderingDirty$jscomp$inline_260 = !0;
namesToPlugins[pluginName$jscomp$inline_262] =
pluginModule$jscomp$inline_263;
isOrderingDirty$jscomp$inline_261 = !0;
}
}
isOrderingDirty$jscomp$inline_260 && recomputePluginOrdering();
isOrderingDirty$jscomp$inline_261 && recomputePluginOrdering();
var emptyObject$1 = {},
removedKeys = null,
removedKeyCount = 0,
Expand Down Expand Up @@ -10259,10 +10259,10 @@ batchedUpdatesImpl = function (fn, a) {
}
};
var roots = new Map(),
devToolsConfig$jscomp$inline_1126 = {
devToolsConfig$jscomp$inline_1130 = {
findFiberByHostInstance: getInstanceFromNode,
bundleType: 0,
version: "18.3.0-next-4a1cc2ddd-20230403",
version: "18.3.0-next-0700dd50b-20230404",
rendererPackageName: "react-native-renderer",
rendererConfig: {
getInspectorDataForViewTag: function () {
Expand Down Expand Up @@ -10291,10 +10291,10 @@ var roots = new Map(),
} catch (err) {}
return hook.checkDCE ? !0 : !1;
})({
bundleType: devToolsConfig$jscomp$inline_1126.bundleType,
version: devToolsConfig$jscomp$inline_1126.version,
rendererPackageName: devToolsConfig$jscomp$inline_1126.rendererPackageName,
rendererConfig: devToolsConfig$jscomp$inline_1126.rendererConfig,
bundleType: devToolsConfig$jscomp$inline_1130.bundleType,
version: devToolsConfig$jscomp$inline_1130.version,
rendererPackageName: devToolsConfig$jscomp$inline_1130.rendererPackageName,
rendererConfig: devToolsConfig$jscomp$inline_1130.rendererConfig,
overrideHookState: null,
overrideHookStateDeletePath: null,
overrideHookStateRenamePath: null,
Expand All @@ -10310,14 +10310,14 @@ var roots = new Map(),
return null === fiber ? null : fiber.stateNode;
},
findFiberByHostInstance:
devToolsConfig$jscomp$inline_1126.findFiberByHostInstance ||
devToolsConfig$jscomp$inline_1130.findFiberByHostInstance ||
emptyFindFiberByHostInstance,
findHostInstancesForRefresh: null,
scheduleRefresh: null,
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-4a1cc2ddd-20230403"
reconcilerVersion: "18.3.0-next-0700dd50b-20230404"
});
exports.createPortal = function (children, containerTag) {
return createPortal$1(
Expand Down Expand Up @@ -10395,6 +10395,15 @@ exports.getNodeFromInternalInstanceHandle = function (internalInstanceHandle) {
exports.getPublicInstanceFromInternalInstanceHandle = function (
internalInstanceHandle
) {
if (6 === internalInstanceHandle.tag) {
var textInstance = internalInstanceHandle.stateNode;
null == textInstance.publicInstance &&
(textInstance.publicInstance =
ReactNativePrivateInterface.createPublicTextInstance(
internalInstanceHandle
));
return textInstance.publicInstance;
}
return getPublicInstance(internalInstanceHandle.stateNode);
};
exports.render = function (element, containerTag, callback, concurrentRoot) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27698,7 +27698,7 @@ function createFiberRoot(
return root;
}

var ReactVersion = "18.3.0-next-4a1cc2ddd-20230403";
var ReactVersion = "18.3.0-next-0700dd50b-20230404";

function createPortal$1(
children,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9810,7 +9810,7 @@ var roots = new Map(),
devToolsConfig$jscomp$inline_1107 = {
findFiberByHostInstance: getInstanceFromTag,
bundleType: 0,
version: "18.3.0-next-4a1cc2ddd-20230403",
version: "18.3.0-next-0700dd50b-20230404",
rendererPackageName: "react-native-renderer",
rendererConfig: {
getInspectorDataForViewTag: function () {
Expand Down Expand Up @@ -9852,7 +9852,7 @@ var internals$jscomp$inline_1359 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-4a1cc2ddd-20230403"
reconcilerVersion: "18.3.0-next-0700dd50b-20230404"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1360 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
Expand Down
Loading

0 comments on commit 08375e6

Please sign in to comment.