Skip to content

Commit da1ccb2

Browse files
committed
feat(utils): Add function to extract relevant component name
1 parent c85b2e4 commit da1ccb2

File tree

1 file changed

+34
-4
lines changed

1 file changed

+34
-4
lines changed

packages/utils/src/browser.ts

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ const WINDOW = getGlobalObject<Window>();
66

77
const DEFAULT_MAX_STRING_LENGTH = 80;
88

9+
type SimpleNode = {
10+
parentNode: SimpleNode;
11+
} | null;
12+
913
/**
1014
* Given a child DOM element, returns a query-selector statement describing that
1115
* and its ancestors
@@ -16,10 +20,6 @@ export function htmlTreeAsString(
1620
elem: unknown,
1721
options: string[] | { keyAttrs?: string[]; maxStringLength?: number } = {},
1822
): string {
19-
type SimpleNode = {
20-
parentNode: SimpleNode;
21-
} | null;
22-
2323
if (!elem) {
2424
return '<unknown>';
2525
}
@@ -86,6 +86,11 @@ function _htmlElementAsString(el: unknown, keyAttrs?: string[]): string {
8686
return '';
8787
}
8888

89+
// If using the component name annotation plugin, this value may be available on the DOM node
90+
if (elem instanceof HTMLElement && elem.dataset && elem.dataset['sentryComponent']) {
91+
return elem.dataset['sentryComponent'];
92+
}
93+
8994
out.push(elem.tagName.toLowerCase());
9095

9196
// Pairs of attribute keys defined in `serializeAttribute` and their values on element.
@@ -157,3 +162,28 @@ export function getDomElement<E = any>(selector: string): E | null {
157162
}
158163
return null;
159164
}
165+
166+
/**
167+
* Given a DOM element, traverses up the tree until it finds the first ancestor node
168+
* that has the `data-sentry-component` attribute. This attribute is added at build-time
169+
* by projects that have the component name annotation plugin installed.
170+
*
171+
* @returns a string representation of the component for the provided DOM element, or `null` if not found
172+
*/
173+
export function getComponentName(elem: unknown): string | null {
174+
let currentElem = elem as SimpleNode;
175+
const MAX_TRAVERSE_HEIGHT = 5;
176+
for (let i = 0; i < MAX_TRAVERSE_HEIGHT; i++) {
177+
if (!currentElem) {
178+
return null;
179+
}
180+
181+
if (currentElem instanceof HTMLElement && currentElem.dataset['sentryComponent']) {
182+
return currentElem.dataset['sentryComponent'];
183+
}
184+
185+
currentElem = currentElem.parentNode;
186+
}
187+
188+
return null;
189+
}

0 commit comments

Comments
 (0)