Files
klz-cables.com/.pnpm-store/v10/files/1b/e9c2e4a7e7317e41c87478b141eb8adb7f0f4293341a56ff2f8fc208830df5562c887a948bceedaed3a2f1572e717368eee0c2aeb842124da27291b2104bd8
Marc Mintel 5397309103
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
fix(products): fix breadcrumbs and product filtering (backport from main)
2026-02-24 16:04:21 +01:00

1 line
14 KiB
Plaintext

{"version":3,"file":"dom.js","sources":["../../../src/instrument/dom.ts"],"sourcesContent":["import type { HandlerDataDom } from '@sentry/core';\nimport { addHandler, addNonEnumerableProperty, fill, maybeInstrument, triggerHandlers, uuid4 } from '@sentry/core';\nimport { WINDOW } from '../types';\n\ntype SentryWrappedTarget = HTMLElement & { _sentryId?: string };\n\ntype AddEventListener = (\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n) => void;\ntype RemoveEventListener = (\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n) => void;\n\ntype InstrumentedElement = Element & {\n __sentry_instrumentation_handlers__?: {\n [key in 'click' | 'keypress']?: {\n handler?: unknown;\n /** The number of custom listeners attached to this element */\n refCount: number;\n };\n };\n};\n\nconst DEBOUNCE_DURATION = 1000;\n\nlet debounceTimerID: number | undefined;\nlet lastCapturedEventType: string | undefined;\nlet lastCapturedEventTargetId: string | undefined;\n\n/**\n * Add an instrumentation handler for when a click or a keypress happens.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nexport function addClickKeypressInstrumentationHandler(handler: (data: HandlerDataDom) => void): void {\n const type = 'dom';\n addHandler(type, handler);\n maybeInstrument(type, instrumentDOM);\n}\n\n/** Exported for tests only. */\nexport function instrumentDOM(): void {\n if (!WINDOW.document) {\n return;\n }\n\n // Make it so that any click or keypress that is unhandled / bubbled up all the way to the document triggers our dom\n // handlers. (Normally we have only one, which captures a breadcrumb for each click or keypress.) Do this before\n // we instrument `addEventListener` so that we don't end up attaching this handler twice.\n const triggerDOMHandler = triggerHandlers.bind(null, 'dom');\n const globalDOMEventHandler = makeDOMEventHandler(triggerDOMHandler, true);\n WINDOW.document.addEventListener('click', globalDOMEventHandler, false);\n WINDOW.document.addEventListener('keypress', globalDOMEventHandler, false);\n\n // After hooking into click and keypress events bubbled up to `document`, we also hook into user-handled\n // clicks & keypresses, by adding an event listener of our own to any element to which they add a listener. That\n // way, whenever one of their handlers is triggered, ours will be, too. (This is needed because their handler\n // could potentially prevent the event from bubbling up to our global listeners. This way, our handler are still\n // guaranteed to fire at least once.)\n ['EventTarget', 'Node'].forEach((target: string) => {\n const globalObject = WINDOW as unknown as Record<string, { prototype?: object }>;\n const proto = globalObject[target]?.prototype;\n\n // eslint-disable-next-line no-prototype-builtins\n if (!proto?.hasOwnProperty?.('addEventListener')) {\n return;\n }\n\n fill(proto, 'addEventListener', function (originalAddEventListener: AddEventListener): AddEventListener {\n return function (this: InstrumentedElement, type, listener, options): AddEventListener {\n if (type === 'click' || type == 'keypress') {\n try {\n const handlers = (this.__sentry_instrumentation_handlers__ =\n this.__sentry_instrumentation_handlers__ || {});\n const handlerForType = (handlers[type] = handlers[type] || { refCount: 0 });\n\n if (!handlerForType.handler) {\n const handler = makeDOMEventHandler(triggerDOMHandler);\n handlerForType.handler = handler;\n originalAddEventListener.call(this, type, handler, options);\n }\n\n handlerForType.refCount++;\n } catch {\n // Accessing dom properties is always fragile.\n // Also allows us to skip `addEventListeners` calls with no proper `this` context.\n }\n }\n\n return originalAddEventListener.call(this, type, listener, options);\n };\n });\n\n fill(\n proto,\n 'removeEventListener',\n function (originalRemoveEventListener: RemoveEventListener): RemoveEventListener {\n return function (this: InstrumentedElement, type, listener, options): () => void {\n if (type === 'click' || type == 'keypress') {\n try {\n const handlers = this.__sentry_instrumentation_handlers__ || {};\n const handlerForType = handlers[type];\n\n if (handlerForType) {\n handlerForType.refCount--;\n // If there are no longer any custom handlers of the current type on this element, we can remove ours, too.\n if (handlerForType.refCount <= 0) {\n originalRemoveEventListener.call(this, type, handlerForType.handler, options);\n handlerForType.handler = undefined;\n delete handlers[type]; // eslint-disable-line @typescript-eslint/no-dynamic-delete\n }\n\n // If there are no longer any custom handlers of any type on this element, cleanup everything.\n if (Object.keys(handlers).length === 0) {\n delete this.__sentry_instrumentation_handlers__;\n }\n }\n } catch {\n // Accessing dom properties is always fragile.\n // Also allows us to skip `addEventListeners` calls with no proper `this` context.\n }\n }\n\n return originalRemoveEventListener.call(this, type, listener, options);\n };\n },\n );\n });\n}\n\n/**\n * Check whether the event is similar to the last captured one. For example, two click events on the same button.\n */\nfunction isSimilarToLastCapturedEvent(event: Event): boolean {\n // If both events have different type, then user definitely performed two separate actions. e.g. click + keypress.\n if (event.type !== lastCapturedEventType) {\n return false;\n }\n\n try {\n // If both events have the same type, it's still possible that actions were performed on different targets.\n // e.g. 2 clicks on different buttons.\n if (!event.target || (event.target as SentryWrappedTarget)._sentryId !== lastCapturedEventTargetId) {\n return false;\n }\n } catch {\n // just accessing `target` property can throw an exception in some rare circumstances\n // see: https://github.com/getsentry/sentry-javascript/issues/838\n }\n\n // If both events have the same type _and_ same `target` (an element which triggered an event, _not necessarily_\n // to which an event listener was attached), we treat them as the same action, as we want to capture\n // only one breadcrumb. e.g. multiple clicks on the same button, or typing inside a user input box.\n return true;\n}\n\n/**\n * Decide whether an event should be captured.\n * @param event event to be captured\n */\nfunction shouldSkipDOMEvent(eventType: string, target: SentryWrappedTarget | null): boolean {\n // We are only interested in filtering `keypress` events for now.\n if (eventType !== 'keypress') {\n return false;\n }\n\n if (!target?.tagName) {\n return true;\n }\n\n // Only consider keypress events on actual input elements. This will disregard keypresses targeting body\n // e.g.tabbing through elements, hotkeys, etc.\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Wraps addEventListener to capture UI breadcrumbs\n */\nfunction makeDOMEventHandler(\n handler: (data: HandlerDataDom) => void,\n globalListener: boolean = false,\n): (event: Event) => void {\n return (event: Event & { _sentryCaptured?: true }): void => {\n // It's possible this handler might trigger multiple times for the same\n // event (e.g. event propagation through node ancestors).\n // Ignore if we've already captured that event.\n if (!event || event['_sentryCaptured']) {\n return;\n }\n\n const target = getEventTarget(event);\n\n // We always want to skip _some_ events.\n if (shouldSkipDOMEvent(event.type, target)) {\n return;\n }\n\n // Mark event as \"seen\"\n addNonEnumerableProperty(event, '_sentryCaptured', true);\n\n if (target && !target._sentryId) {\n // Add UUID to event target so we can identify if\n addNonEnumerableProperty(target, '_sentryId', uuid4());\n }\n\n const name = event.type === 'keypress' ? 'input' : event.type;\n\n // If there is no last captured event, it means that we can safely capture the new event and store it for future comparisons.\n // If there is a last captured event, see if the new event is different enough to treat it as a unique one.\n // If that's the case, emit the previous event and store locally the newly-captured DOM event.\n if (!isSimilarToLastCapturedEvent(event)) {\n const handlerData: HandlerDataDom = { event, name, global: globalListener };\n handler(handlerData);\n lastCapturedEventType = event.type;\n lastCapturedEventTargetId = target ? target._sentryId : undefined;\n }\n\n // Start a new debounce timer that will prevent us from capturing multiple events that should be grouped together.\n clearTimeout(debounceTimerID);\n debounceTimerID = WINDOW.setTimeout(() => {\n lastCapturedEventTargetId = undefined;\n lastCapturedEventType = undefined;\n }, DEBOUNCE_DURATION);\n };\n}\n\nfunction getEventTarget(event: Event): SentryWrappedTarget | null {\n try {\n return event.target as SentryWrappedTarget | null;\n } catch {\n // just accessing `target` property can throw an exception in some rare circumstances\n // see: https://github.com/getsentry/sentry-javascript/issues/838\n return null;\n }\n}\n"],"names":[],"mappings":"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"}