Implement tagName property in ReadOnlyElement (#39278)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39278

Implements tagName as the name of the component prefixed with `RN:`.

Changelog: [internal]

Reviewed By: NickGerleman

Differential Revision: D48951824

fbshipit-source-id: 4a8387adff8ed504423d7ead7b95943bfd77ae8c
This commit is contained in:
Rubén Norte
2023-09-07 12:01:46 -07:00
committed by Facebook GitHub Bot
parent cbf3b7d27c
commit 447d80ee51
4 changed files with 54 additions and 1 deletions
@@ -137,7 +137,13 @@ export default class ReadOnlyElement extends ReadOnlyNode {
}
get tagName(): string {
throw new TypeError('Unimplemented');
const node = getShadowNode(this);
if (node != null) {
return nullthrows(getFabricUIManager()).getTagName(node);
}
return '';
}
get textContent(): string | null {
@@ -91,6 +91,7 @@ export interface Spec {
+getScrollPosition: (
node: Node,
) => ?[/* scrollLeft: */ number, /* scrollTop: */ number];
+getTagName: (node: Node) => string;
/**
* Support methods for the Pointer Capture APIs.
@@ -131,6 +132,10 @@ const CACHED_PROPERTIES = [
'getBoundingClientRect',
'getOffset',
'getScrollPosition',
'getTagName',
'hasPointerCapture',
'setPointerCapture',
'releasePointerCapture',
];
// This is exposed as a getter because apps using the legacy renderer AND
@@ -497,6 +497,11 @@ const FabricUIManagerMock: IFabricUIManagerMock = {
},
),
getTagName: jest.fn((node: Node): string => {
ensureHostNode(node);
return 'RN:' + fromNode(node).viewName;
}),
__getInstanceHandleFromNode(node: Node): InternalInstanceHandle {
return fromNode(node).instanceHandle;
},
@@ -1207,6 +1207,43 @@ jsi::Value UIManagerBinding::get(
});
}
if (methodName == "getTagName") {
// This is a method to access the normalized tag name of a shadow node, to
// implement `Element.prototype.tagName` (see
// https://developer.mozilla.org/en-US/docs/Web/API/Element/tagName).
// getTagName(shadowNode: ShadowNode): string
auto paramCount = 1;
return jsi::Function::createFromHostFunction(
runtime,
name,
paramCount,
[methodName, paramCount](
jsi::Runtime& runtime,
const jsi::Value& /*thisValue*/,
const jsi::Value* arguments,
size_t count) -> jsi::Value {
validateArgumentCount(runtime, methodName, paramCount, count);
auto shadowNode = shadowNodeFromValue(runtime, arguments[0]);
std::string canonicalComponentName = shadowNode->getComponentName();
// FIXME(T162807327): Remove Android-specific prefixes and unify
// shadow node implementations
if (canonicalComponentName == "AndroidTextInput") {
canonicalComponentName = "TextInput";
} else if (canonicalComponentName == "AndroidSwitch") {
canonicalComponentName = "Switch";
}
// Prefix with RN:
canonicalComponentName.insert(0, "RN:");
return jsi::String::createFromUtf8(runtime, canonicalComponentName);
});
}
/**
* Pointer Capture APIs
*/