Skip to content

Commit

Permalink
Implement tagName property in ReadOnlyElement (facebook#39278)
Browse files Browse the repository at this point in the history
Summary:

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

Changelog: [internal]

Reviewed By: NickGerleman

Differential Revision: D48951824
  • Loading branch information
rubennorte authored and facebook-github-bot committed Sep 7, 2023
1 parent a228b0f commit 4de4351
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 1 deletion.
8 changes: 7 additions & 1 deletion packages/react-native/Libraries/DOM/Nodes/ReadOnlyElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down

0 comments on commit 4de4351

Please sign in to comment.