UNPKG

@datataki/client

Version:

A lightweight client-side event tracking library for modern web applications. Track user sessions, page views, interactions and custom events with minimal setup.

1 lines 3.22 kB
Object.defineProperty(exports,"__esModule",{value:!0}),exports.ClickHandler=void 0;var t=require("../managers/state.manager");let i=require("../types/event.types"),r="data-taki",n=255,l=["button","a",'input[type="button"]','input[type="submit"]','input[type="reset"]','input[type="checkbox"]','input[type="radio"]',"select","textarea",'[role="button"]','[role="link"]','[role="tab"]','[role="menuitem"]','[role="option"]','[role="checkbox"]','[role="radio"]','[role="switch"]',"[routerLink]","[ng-click]","[data-action]","[data-click]","[data-navigate]","[data-toggle]","[onclick]",".btn",".button",".clickable",".nav-link",".menu-item","[data-testid]",'[tabindex="0"]'];class e extends t.StateManager{constructor(t){super(),this.eventManager=t}startTracking(){this.clickHandler||(this.clickHandler=t=>{var e,a,r=t.target;r&&(a=this.findTrackingElement(r),e=this.getRelevantClickElement(r),t=this.calculateClickCoordinates(t,r),a&&(a=this.extractTrackingData(a))&&(a=this.createCustomEventData(a),this.eventManager.track({type:i.EventType.CUSTOM,custom_event:{name:a.name,...a.value&&{metadata:{value:a.value}}}})),a=this.generateClickData(r,e,t),this.eventManager.track({type:i.EventType.CLICK,page_url:window.location.href,click_data:a}))},window.addEventListener("click",this.clickHandler,!0))}stopTracking(){this.clickHandler&&(window.removeEventListener("click",this.clickHandler,!0),this.clickHandler=void 0)}findTrackingElement(t){return t.hasAttribute(r+"-name")?t:t.closest(`[${r}-name]`)||void 0}getRelevantClickElement(t){for(var e of l)try{if(t.matches(e))return t}catch{continue}for(var a of l)try{var r=t.closest(a);if(r)return r}catch{continue}return t}calculateClickCoordinates(t,e){var e=e.getBoundingClientRect(),a=t.clientX,t=t.clientY;return{x:a,y:t,relativeX:0<e.width?Math.max(0,Math.min(1,Number(((a-e.left)/e.width).toFixed(3)))):0,relativeY:0<e.height?Math.max(0,Math.min(1,Number(((t-e.top)/e.height).toFixed(3)))):0}}extractTrackingData(t){var e=t.getAttribute(r+"-name"),a=t.getAttribute(r+"-value");if(e)return{element:t,name:e,...a&&{value:a}}}generateClickData(t,e,a){var{x:a,y:r,relativeX:i,relativeY:n}=a,t=this.getRelevantText(t,e),l=this.extractElementAttributes(e),c=e.getAttribute("href"),o=e.getAttribute("title"),s=e.getAttribute("alt"),u=e.getAttribute("role"),d=e.getAttribute("aria-label");return{x:a,y:r,relativeX:i,relativeY:n,tag:e.tagName.toLowerCase(),...e.id&&{id:e.id},...e.className&&{class:e.className},...t&&{text:t},...c&&{href:c},...o&&{title:o},...s&&{alt:s},...u&&{role:u},...d&&{ariaLabel:d},...0<Object.keys(l).length&&{dataAttributes:l}}}getRelevantText(t,e){var a,t=t.textContent?.trim()??"",r=e.textContent?.trim()??"";return t||r?t&&t.length<=n?t:(e=["main","section","article","body","html","header","footer","aside","nav"].includes(e.tagName.toLowerCase()),a=510<r.length,e&&a?t&&t.length<=n?t:"":r.length<=n?r:t&&t.length<.1*r.length?t.length<=n?t:t.slice(0,n)+"...":r.slice(0,n)+"..."):""}extractElementAttributes(t){var e,a={};for(e of["id","class","data-testid","aria-label","title","href","type","name"]){var r=t.getAttribute(e);r&&(a[e]=r)}return a}createCustomEventData(t){return{name:t.name,...t.value&&{value:t.value}}}}exports.ClickHandler=e;