clarity-js 0.8.13-beta → 0.8.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,13 +13,9 @@ export function report(e: Error): Error {
13
13
  if (history && history.indexOf(e.message) === -1) {
14
14
  const url = config.report;
15
15
  if (url && url.length > 0 && data) {
16
- const payload: Report = { v: data.version, p: data.projectId, u: data.userId, s: data.sessionId, n: data.pageNum };
17
- if (e.message) {
18
- payload.m = e.message;
19
- }
20
- if (e.stack) {
21
- payload.e = e.stack;
22
- }
16
+ let payload: Report = {v: data.version, p: data.projectId, u: data.userId, s: data.sessionId, n: data.pageNum};
17
+ if (e.message) { payload.m = e.message; }
18
+ if (e.stack) { payload.e = e.stack; }
23
19
  // Using POST request instead of a GET request (img-src) to not violate existing CSP rules
24
20
  // Since, Clarity already uses XHR to upload data, we stick with similar POST mechanism for reporting too
25
21
  let xhr = new XMLHttpRequest();
package/src/core/scrub.ts CHANGED
@@ -41,7 +41,13 @@ export function text(value: string, hint: string, privacy: Privacy, mangle: bool
41
41
  case "srcset":
42
42
  case "title":
43
43
  case "alt":
44
- return privacy === Privacy.TextImage ? Data.Constant.Empty : value;
44
+ if (privacy === Privacy.TextImage) {
45
+ if (hint === 'src' && value?.startsWith('blob:')) {
46
+ return 'blob:';
47
+ }
48
+ return Data.Constant.Empty;
49
+ }
50
+ return value;
45
51
  case "value":
46
52
  case "click":
47
53
  case "input":
@@ -1,2 +1,2 @@
1
- let version = "0.8.13-beta";
1
+ let version = "0.8.15";
2
2
  export default version;
@@ -9,6 +9,7 @@ import * as dimension from "@src/data/dimension";
9
9
  import * as metric from "@src/data/metric";
10
10
  import { set } from "@src/data/variable";
11
11
  import * as trackConsent from "@src/data/consent";
12
+ import { Constant as CoreConstant } from "@clarity-types/core";
12
13
 
13
14
  export let data: Metadata = null;
14
15
  export let callbacks: MetadataCallbackOptions[] = [];
@@ -54,6 +55,13 @@ export function start(): void {
54
55
  metric.max(Metric.Playback, BooleanFlag.False);
55
56
  metric.max(Metric.Electron, electron);
56
57
 
58
+ const zone = (window as any)?.[CoreConstant.Zone];
59
+ const isZone = zone && CoreConstant.Symbol in zone;
60
+
61
+ if (isZone) {
62
+ metric.max(Metric.AngularZone, BooleanFlag.True);
63
+ }
64
+
57
65
  // Capture navigator specific dimensions
58
66
  if (navigator) {
59
67
  dimension.log(Dimension.Language, navigator.language);
@@ -124,12 +124,12 @@ export function reset(): void {
124
124
  }
125
125
 
126
126
  function similar(last: PointerState, current: PointerState): boolean {
127
- const dx = last.data.x - current.data.x;
128
- const dy = last.data.y - current.data.y;
129
- const distance = Math.sqrt(dx * dx + dy * dy);
130
- const gap = current.time - last.time;
131
- const match = current.data.target === last.data.target;
132
- const sameId = current.data.id !== undefined ? current.data.id === last.data.id : true;
127
+ let dx = last.data.x - current.data.x;
128
+ let dy = last.data.y - current.data.y;
129
+ let distance = Math.sqrt(dx * dx + dy * dy);
130
+ let gap = current.time - last.time;
131
+ let match = current.data.target === last.data.target;
132
+ let sameId = current.data.id !== undefined ? current.data.id === last.data.id : true;
133
133
  return current.event === last.event && match && distance < Setting.Distance && gap < Setting.PointerInterval && sameId;
134
134
  }
135
135
 
@@ -6,10 +6,10 @@ import { schedule } from "@src/core/task";
6
6
  import { time } from "@src/core/time";
7
7
  import { clearTimeout, setTimeout } from "@src/core/timeout";
8
8
  import throttle from "@src/core/throttle";
9
- import * as dimension from "@src/data/dimension";
10
9
  import { iframe } from "@src/layout/dom";
11
10
  import { target, metadata } from "@src/layout/target";
12
11
  import encode from "./encode";
12
+ import * as dimension from "@src/data/dimension";
13
13
 
14
14
  export let state: ScrollState[] = [];
15
15
  let initialTop: Node = null;
@@ -22,8 +22,8 @@ export function start(): void {
22
22
  }
23
23
 
24
24
  export function observe(root: Node): void {
25
- const frame = iframe(root);
26
- const node = frame ? frame.contentWindow : root === document ? window : root;
25
+ let frame = iframe(root);
26
+ let node = frame ? frame.contentWindow : (root === document ? window : root);
27
27
  bind(node, "scroll", throttledRecompute, true);
28
28
  }
29
29
 
@@ -102,9 +102,9 @@ function process(event: Event): void {
102
102
  }
103
103
 
104
104
  function similar(last: ScrollState, current: ScrollState): boolean {
105
- const dx = last.data.x - current.data.x;
106
- const dy = last.data.y - current.data.y;
107
- return dx * dx + dy * dy < Setting.Distance * Setting.Distance && current.time - last.time < Setting.ScrollInterval;
105
+ let dx = last.data.x - current.data.x;
106
+ let dy = last.data.y - current.data.y;
107
+ return (dx * dx + dy * dy < Setting.Distance * Setting.Distance) && (current.time - last.time < Setting.ScrollInterval);
108
108
  }
109
109
 
110
110
  export function compute(): void {
@@ -90,12 +90,9 @@ function handler(entries: IntersectionObserverEntry[]): void {
90
90
  // like search box - one for desktop, and another for mobile. In those cases, CSS media queries determine which one should be visible.
91
91
  // Also, if these regions ever become non-zero width or height (through AJAX, user action or orientation change) - we will automatically start monitoring them from that point onwards
92
92
  if (regionMap.has(target) && rect.width + rect.height > 0 && viewport && viewport.width > 0 && viewport.height > 0) {
93
- const id = target ? dom.getId(target) : null;
94
- const data =
95
- id in regions
96
- ? regions[id]
97
- : { id, name: regionMap.get(target), interaction: InteractionState.None, visibility: RegionVisibility.Rendered };
98
-
93
+ let id = target ? dom.getId(target) : null;
94
+ let data = id in regions ? regions[id] : { id, name: regionMap.get(target), interaction: InteractionState.None, visibility: RegionVisibility.Rendered };
95
+
99
96
  // For regions that have relatively smaller area, we look at intersection ratio and see the overlap relative to element's area
100
97
  // However, for larger regions, area of regions could be bigger than viewport and therefore comparison is relative to visible area
101
98
  let viewportRatio = overlap ? (overlap.width * overlap.height * 1.0) / (viewport.width * viewport.height) : 0;
@@ -1,4 +1,4 @@
1
- import { Event } from "@clarity-types/data";
1
+ import { Event, Metric } from "@clarity-types/data";
2
2
  import { StyleSheetOperation, StyleSheetState } from "@clarity-types/layout";
3
3
  import { time } from "@src/core/time";
4
4
  import { shortid } from "@src/data/metadata";
package/types/data.d.ts CHANGED
@@ -131,7 +131,8 @@ export const enum Metric {
131
131
  * @deprecated Move it to dimension as it'll report only last value
132
132
  */
133
133
  InteractionNextPaint = 37,
134
- HistoryClear = 38
134
+ HistoryClear = 38,
135
+ AngularZone = 39,
135
136
  }
136
137
 
137
138
  export const enum Dimension {
@@ -18,7 +18,6 @@ export const enum Setting {
18
18
  ScrollInterval = 50, // 25 milliseconds
19
19
  PointerInterval = 25, // 25 milliseconds
20
20
  Throttle = 25, // 25 milliseconds
21
- // biome-ignore lint/style/useLiteralEnumMembers: Time.Second is a const enum, it is compiled to a number
22
21
  TimelineSpan = 2 * Time.Second, // 2 seconds
23
22
  }
24
23