diff --git a/packages/browser-utils/src/component-name.ts b/packages/browser-utils/src/component-name.ts new file mode 100644 index 000000000000..fdde7f5eb019 --- /dev/null +++ b/packages/browser-utils/src/component-name.ts @@ -0,0 +1,39 @@ +import { GLOBAL_OBJ } from '@sentry/core'; + +type SimpleNode = { + parentNode: SimpleNode; +} | null; + +/** + * Given a DOM element, traverses up the tree until it finds the first ancestor node + * that has the `data-sentry-component` or `data-sentry-element` attribute with `data-sentry-component` taking + * precedence. This attribute is added at build-time by projects that have the component name annotation plugin installed. + * + * @returns a string representation of the component for the provided DOM element, or `null` if not found + */ +export function getComponentName(elem: unknown, maxTraverseHeight: number = 5): string | null { + // @ts-expect-error WINDOW has HTMLElement + if (!GLOBAL_OBJ.HTMLElement) { + return null; + } + + let currentElem = elem as SimpleNode; + for (let i = 0; i < maxTraverseHeight; i++) { + if (!currentElem) { + return null; + } + + if (currentElem instanceof HTMLElement) { + if (currentElem.dataset['sentryComponent']) { + return currentElem.dataset['sentryComponent']; + } + if (currentElem.dataset['sentryElement']) { + return currentElem.dataset['sentryElement']; + } + } + + currentElem = currentElem.parentNode; + } + + return null; +} diff --git a/packages/browser-utils/src/index.ts b/packages/browser-utils/src/index.ts index 95830b7340a1..ca86c78052f0 100644 --- a/packages/browser-utils/src/index.ts +++ b/packages/browser-utils/src/index.ts @@ -44,6 +44,8 @@ export { resourceTimingToSpanAttributes } from './performance/resourceTiming'; export { htmlTreeAsString } from './htmlTreeAsString'; +export { getComponentName } from './component-name'; + export { isElement } from './is'; export { getAbsoluteUrl } from './instrumentation/location'; diff --git a/packages/browser-utils/src/performance/interactions.ts b/packages/browser-utils/src/performance/interactions.ts index 6a6bdb71453e..067b549a707f 100644 --- a/packages/browser-utils/src/performance/interactions.ts +++ b/packages/browser-utils/src/performance/interactions.ts @@ -13,7 +13,6 @@ import { debug, defineIntegration, getActiveSpan, - getComponentName, getRootSpan, spanToJSON, } from '@sentry/core'; @@ -24,6 +23,7 @@ import { addPerformanceInstrumentationHandler } from '../instrumentation/perform import { isBotUserAgent } from '../isBotUserAgent'; import { WINDOW } from '../types'; import { msToSec, startAndEndSpan } from './utils'; +import { getComponentName } from '../component-name'; const INTEGRATION_NAME = 'Interactions'; diff --git a/packages/browser/src/integrations/breadcrumbs.ts b/packages/browser/src/integrations/breadcrumbs.ts index 4517e0a17cd7..936702ca9c6a 100644 --- a/packages/browser/src/integrations/breadcrumbs.ts +++ b/packages/browser/src/integrations/breadcrumbs.ts @@ -23,7 +23,6 @@ import { defineIntegration, getBreadcrumbLogLevelFromHttpStatusCode, getClient, - getComponentName, getEventDescription, parseUrl, safeJoin, @@ -35,6 +34,7 @@ import { addHistoryInstrumentationHandler, addXhrInstrumentationHandler, htmlTreeAsString, + getComponentName, SENTRY_XHR_DATA_KEY, } from '@sentry/browser-utils'; import { DEBUG_BUILD } from '../debug-build'; diff --git a/packages/browser/src/integrations/view-hierarchy.ts b/packages/browser/src/integrations/view-hierarchy.ts index 5073f2ef970e..11be97b4d108 100644 --- a/packages/browser/src/integrations/view-hierarchy.ts +++ b/packages/browser/src/integrations/view-hierarchy.ts @@ -1,5 +1,6 @@ import type { Attachment, Event, EventHint, ViewHierarchyData, ViewHierarchyWindow } from '@sentry/core/browser'; -import { defineIntegration, getComponentName } from '@sentry/core/browser'; +import { defineIntegration } from '@sentry/core/browser'; +import { getComponentName } from '@sentry/browser-utils'; import { WINDOW } from '../helpers'; interface OnElementArgs { diff --git a/packages/core/src/browser-exports.ts b/packages/core/src/browser-exports.ts index 753f65cecbb0..639ba3b90b39 100644 --- a/packages/core/src/browser-exports.ts +++ b/packages/core/src/browser-exports.ts @@ -15,7 +15,7 @@ export { startIdleSpan } from './tracing/idleSpan'; export { spanStreamingIntegration } from './integrations/browserSpanStreaming'; -export { getComponentName, getLocationHref } from './utils/browser'; +export { getLocationHref } from './utils/browser'; export { supportsDOMError, supportsHistory, supportsNativeFetch, supportsReportingObserver } from './utils/supports'; export type { XhrBreadcrumbData, XhrBreadcrumbHint } from './types/breadcrumb'; export type { diff --git a/packages/core/src/utils/browser.ts b/packages/core/src/utils/browser.ts index 9b3e6ec31780..16d4e0b3bff6 100644 --- a/packages/core/src/utils/browser.ts +++ b/packages/core/src/utils/browser.ts @@ -2,10 +2,6 @@ import { GLOBAL_OBJ } from './worldwide'; const WINDOW = GLOBAL_OBJ as unknown as Window; -type SimpleNode = { - parentNode: SimpleNode; -} | null; - /** * A safe form of location.href */ @@ -16,37 +12,3 @@ export function getLocationHref(): string { return ''; } } - -/** - * Given a DOM element, traverses up the tree until it finds the first ancestor node - * that has the `data-sentry-component` or `data-sentry-element` attribute with `data-sentry-component` taking - * precedence. This attribute is added at build-time by projects that have the component name annotation plugin installed. - * - * @returns a string representation of the component for the provided DOM element, or `null` if not found - */ -export function getComponentName(elem: unknown, maxTraverseHeight: number = 5): string | null { - // @ts-expect-error WINDOW has HTMLElement - if (!WINDOW.HTMLElement) { - return null; - } - - let currentElem = elem as SimpleNode; - for (let i = 0; i < maxTraverseHeight; i++) { - if (!currentElem) { - return null; - } - - if (currentElem instanceof HTMLElement) { - if (currentElem.dataset['sentryComponent']) { - return currentElem.dataset['sentryComponent']; - } - if (currentElem.dataset['sentryElement']) { - return currentElem.dataset['sentryElement']; - } - } - - currentElem = currentElem.parentNode; - } - - return null; -}