@@ -6,6 +6,10 @@ const WINDOW = getGlobalObject<Window>();
6
6
7
7
const DEFAULT_MAX_STRING_LENGTH = 80 ;
8
8
9
+ type SimpleNode = {
10
+ parentNode : SimpleNode ;
11
+ } | null ;
12
+
9
13
/**
10
14
* Given a child DOM element, returns a query-selector statement describing that
11
15
* and its ancestors
@@ -16,10 +20,6 @@ export function htmlTreeAsString(
16
20
elem : unknown ,
17
21
options : string [ ] | { keyAttrs ?: string [ ] ; maxStringLength ?: number } = { } ,
18
22
) : string {
19
- type SimpleNode = {
20
- parentNode : SimpleNode ;
21
- } | null ;
22
-
23
23
if ( ! elem ) {
24
24
return '<unknown>' ;
25
25
}
@@ -86,6 +86,14 @@ function _htmlElementAsString(el: unknown, keyAttrs?: string[]): string {
86
86
return '' ;
87
87
}
88
88
89
+ // @ts -expect-error WINDOW has HTMLElement
90
+ if ( WINDOW . HTMLElement ) {
91
+ // If using the component name annotation plugin, this value may be available on the DOM node
92
+ if ( elem instanceof HTMLElement && elem . dataset && elem . dataset [ 'sentryComponent' ] ) {
93
+ return elem . dataset [ 'sentryComponent' ] ;
94
+ }
95
+ }
96
+
89
97
out . push ( elem . tagName . toLowerCase ( ) ) ;
90
98
91
99
// Pairs of attribute keys defined in `serializeAttribute` and their values on element.
@@ -157,3 +165,33 @@ export function getDomElement<E = any>(selector: string): E | null {
157
165
}
158
166
return null ;
159
167
}
168
+
169
+ /**
170
+ * Given a DOM element, traverses up the tree until it finds the first ancestor node
171
+ * that has the `data-sentry-component` attribute. This attribute is added at build-time
172
+ * by projects that have the component name annotation plugin installed.
173
+ *
174
+ * @returns a string representation of the component for the provided DOM element, or `null` if not found
175
+ */
176
+ export function getComponentName ( elem : unknown ) : string | null {
177
+ // @ts -expect-error WINDOW has HTMLElement
178
+ if ( ! WINDOW . HTMLElement ) {
179
+ return null ;
180
+ }
181
+
182
+ let currentElem = elem as SimpleNode ;
183
+ const MAX_TRAVERSE_HEIGHT = 5 ;
184
+ for ( let i = 0 ; i < MAX_TRAVERSE_HEIGHT ; i ++ ) {
185
+ if ( ! currentElem ) {
186
+ return null ;
187
+ }
188
+
189
+ if ( currentElem instanceof HTMLElement && currentElem . dataset [ 'sentryComponent' ] ) {
190
+ return currentElem . dataset [ 'sentryComponent' ] ;
191
+ }
192
+
193
+ currentElem = currentElem . parentNode ;
194
+ }
195
+
196
+ return null ;
197
+ }
0 commit comments