UNPKG

@embrace-io/web-sdk

Version:
86 lines (85 loc) 3.02 kB
import { getSelector } from "../../../utils/getSelector.js"; import { KEY_EMB_TYPE } from "../../../constants/attributes.js"; import { EmbraceInstrumentationBase } from "../../EmbraceInstrumentationBase/EmbraceInstrumentationBase.js"; import { ATTR_RAGE_CLICK_COUNT, ATTR_RAGE_CLICK_ELEMENT_SELECTOR, ATTR_RAGE_CLICK_ELEMENT_TYPE, ATTR_RAGE_CLICK_INTERACTION_TYPE, ATTR_RAGE_CLICK_X, ATTR_RAGE_CLICK_Y, RAGE_CLICK_EVENT_NAME } from "./constants.js"; import { SeverityNumber } from "@opentelemetry/api-logs"; //#region src/instrumentations/rage-click/RageClickInstrumentation/RageClickInstrumentation.ts var RageClickInstrumentation = class extends EmbraceInstrumentationBase { _onClickHandler; _eventWindow = null; constructor({ diag, perf } = {}) { super({ instrumentationName: "RageClickInstrumentation", instrumentationVersion: "1.0.0", diag, perf, config: {} }); this._onClickHandler = (event) => { try { this._handleClick(event); } catch (e) { this._diag.error("failed to process rage-click candidate", e); } }; if (this._config.enabled) this.enable(); } onDisable() { document.removeEventListener("click", this._onClickHandler); this._flush(); } onEnable() { document.addEventListener("click", this._onClickHandler); } _handleClick(event) { if (!(event.target instanceof Element)) return; const target = event.target; const interactionType = event instanceof PointerEvent && event.pointerType === "touch" ? "tap" : "click"; if (this._eventWindow === null) { this._eventWindow = { target, x: event.clientX, y: event.clientY, count: 1, interactionType, timestamp: event.timeStamp, timeoutId: window.setTimeout(() => { try { this._flush(); } catch (e) { this._diag.error("failed to emit rage-click log", e); } }, 500) }; return; } const sameTarget = target === this._eventWindow.target; const dx = Math.abs(event.clientX - this._eventWindow.x); const dy = Math.abs(event.clientY - this._eventWindow.y); if (sameTarget || dx <= 50 && dy <= 50) this._eventWindow.count += 1; } _flush() { if (this._eventWindow === null) return; const eventWindow = this._eventWindow; window.clearTimeout(eventWindow.timeoutId); this._eventWindow = null; if (eventWindow.count < 3) return; this.logger.emit({ timestamp: this.perf.epochMillisFromOrigin(eventWindow.timestamp), eventName: RAGE_CLICK_EVENT_NAME, severityNumber: SeverityNumber.INFO, attributes: { [KEY_EMB_TYPE]: "emb.otel_log", [ATTR_RAGE_CLICK_ELEMENT_TYPE]: eventWindow.target.tagName.toLowerCase(), [ATTR_RAGE_CLICK_ELEMENT_SELECTOR]: getSelector(eventWindow.target), [ATTR_RAGE_CLICK_X]: eventWindow.x, [ATTR_RAGE_CLICK_Y]: eventWindow.y, [ATTR_RAGE_CLICK_COUNT]: eventWindow.count, [ATTR_RAGE_CLICK_INTERACTION_TYPE]: eventWindow.interactionType } }); } }; //#endregion export { RageClickInstrumentation }; //# sourceMappingURL=RageClickInstrumentation.js.map