clarity-js 0.8.11 → 0.8.13-beta

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.
Files changed (90) hide show
  1. package/build/clarity.extended.js +1 -1
  2. package/build/clarity.insight.js +1 -1
  3. package/build/clarity.js +2964 -3181
  4. package/build/clarity.min.js +1 -1
  5. package/build/clarity.module.js +2964 -3181
  6. package/build/clarity.performance.js +1 -1
  7. package/package.json +69 -76
  8. package/rollup.config.ts +88 -84
  9. package/src/clarity.ts +28 -34
  10. package/src/core/config.ts +2 -2
  11. package/src/core/event.ts +32 -36
  12. package/src/core/hash.ts +6 -5
  13. package/src/core/history.ts +11 -10
  14. package/src/core/index.ts +11 -21
  15. package/src/core/measure.ts +5 -9
  16. package/src/core/report.ts +3 -3
  17. package/src/core/scrub.ts +20 -29
  18. package/src/core/task.ts +45 -73
  19. package/src/core/time.ts +3 -3
  20. package/src/core/timeout.ts +2 -2
  21. package/src/core/version.ts +1 -1
  22. package/src/data/baseline.ts +55 -60
  23. package/src/data/consent.ts +2 -2
  24. package/src/data/custom.ts +13 -8
  25. package/src/data/dimension.ts +7 -11
  26. package/src/data/encode.ts +30 -36
  27. package/src/data/envelope.ts +38 -38
  28. package/src/data/extract.ts +77 -86
  29. package/src/data/index.ts +6 -10
  30. package/src/data/limit.ts +1 -1
  31. package/src/data/metadata.ts +266 -305
  32. package/src/data/metric.ts +8 -18
  33. package/src/data/ping.ts +4 -8
  34. package/src/data/signal.ts +18 -18
  35. package/src/data/summary.ts +4 -6
  36. package/src/data/token.ts +8 -10
  37. package/src/data/upgrade.ts +3 -7
  38. package/src/data/upload.ts +49 -100
  39. package/src/data/variable.ts +20 -27
  40. package/src/diagnostic/encode.ts +2 -2
  41. package/src/diagnostic/fraud.ts +4 -3
  42. package/src/diagnostic/internal.ts +5 -11
  43. package/src/diagnostic/script.ts +8 -12
  44. package/src/global.ts +1 -1
  45. package/src/insight/blank.ts +4 -4
  46. package/src/insight/encode.ts +17 -23
  47. package/src/insight/snapshot.ts +37 -57
  48. package/src/interaction/change.ts +6 -9
  49. package/src/interaction/click.ts +28 -34
  50. package/src/interaction/clipboard.ts +2 -2
  51. package/src/interaction/encode.ts +31 -35
  52. package/src/interaction/input.ts +9 -11
  53. package/src/interaction/pointer.ts +24 -35
  54. package/src/interaction/resize.ts +5 -5
  55. package/src/interaction/scroll.ts +11 -14
  56. package/src/interaction/selection.ts +8 -12
  57. package/src/interaction/submit.ts +2 -2
  58. package/src/interaction/timeline.ts +9 -13
  59. package/src/interaction/unload.ts +1 -1
  60. package/src/interaction/visibility.ts +2 -2
  61. package/src/layout/animation.ts +41 -47
  62. package/src/layout/discover.ts +5 -5
  63. package/src/layout/document.ts +19 -31
  64. package/src/layout/dom.ts +91 -141
  65. package/src/layout/encode.ts +37 -52
  66. package/src/layout/mutation.ts +318 -321
  67. package/src/layout/node.ts +81 -104
  68. package/src/layout/offset.ts +6 -7
  69. package/src/layout/region.ts +40 -60
  70. package/src/layout/schema.ts +8 -15
  71. package/src/layout/selector.ts +25 -47
  72. package/src/layout/style.ts +36 -44
  73. package/src/layout/target.ts +10 -14
  74. package/src/layout/traverse.ts +11 -17
  75. package/src/performance/blank.ts +1 -1
  76. package/src/performance/encode.ts +4 -4
  77. package/src/performance/interaction.ts +70 -58
  78. package/src/performance/navigation.ts +2 -2
  79. package/src/performance/observer.ts +26 -59
  80. package/src/queue.ts +9 -16
  81. package/tsconfig.json +1 -1
  82. package/tslint.json +32 -25
  83. package/types/core.d.ts +13 -13
  84. package/types/data.d.ts +29 -32
  85. package/types/diagnostic.d.ts +1 -1
  86. package/types/interaction.d.ts +4 -4
  87. package/types/layout.d.ts +21 -36
  88. package/types/performance.d.ts +5 -6
  89. package/.lintstagedrc.yml +0 -3
  90. package/biome.json +0 -43
@@ -1,8 +1,9 @@
1
- import { Constant, Event, type Token } from "@clarity-types/data";
1
+ import { Constant, Event, Token } from "@clarity-types/data";
2
2
  import * as scrub from "@src/core/scrub";
3
3
  import { time } from "@src/core/time";
4
4
  import * as baseline from "@src/data/baseline";
5
5
  import { queue } from "@src/data/upload";
6
+ import { metadata } from "@src/layout/target";
6
7
  import * as change from "@src/interaction/change";
7
8
  import * as click from "@src/interaction/click";
8
9
  import * as clipboard from "@src/interaction/clipboard";
@@ -15,10 +16,9 @@ import * as submit from "@src/interaction/submit";
15
16
  import * as timeline from "@src/interaction/timeline";
16
17
  import * as unload from "@src/interaction/unload";
17
18
  import * as visibility from "@src/interaction/visibility";
18
- import { metadata } from "@src/layout/target";
19
19
 
20
20
  export default async function (type: Event, ts: number = null): Promise<void> {
21
- const t = ts || time();
21
+ let t = ts || time();
22
22
  let tokens: Token[] = [t, type];
23
23
  switch (type) {
24
24
  case Event.MouseDown:
@@ -30,15 +30,15 @@ export default async function (type: Event, ts: number = null): Promise<void> {
30
30
  case Event.TouchEnd:
31
31
  case Event.TouchMove:
32
32
  case Event.TouchCancel:
33
- for (const entry of pointer.state) {
34
- const pTarget = metadata(entry.data.target as Node, entry.event);
33
+ for (let entry of pointer.state) {
34
+ let pTarget = metadata(entry.data.target as Node, entry.event);
35
35
  if (pTarget.id > 0) {
36
36
  tokens = [entry.time, entry.event];
37
37
  tokens.push(pTarget.id);
38
38
  tokens.push(entry.data.x);
39
39
  tokens.push(entry.data.y);
40
- if (entry.data.id !== undefined) {
41
- tokens.push(entry.data.id);
40
+ if (entry.data.id !== undefined) {
41
+ tokens.push(entry.data.id);
42
42
 
43
43
  if (entry.data.isPrimary !== undefined) {
44
44
  tokens.push(entry.data.isPrimary.toString());
@@ -53,10 +53,10 @@ export default async function (type: Event, ts: number = null): Promise<void> {
53
53
  pointer.reset();
54
54
  break;
55
55
  case Event.Click:
56
- for (const entry of click.state) {
57
- const cTarget = metadata(entry.data.target as Node, entry.event, entry.data.text);
56
+ for (let entry of click.state) {
57
+ let cTarget = metadata(entry.data.target as Node, entry.event, entry.data.text);
58
58
  tokens = [entry.time, entry.event];
59
- const cHash = cTarget.hash ? cTarget.hash.join(Constant.Dot) : Constant.Empty;
59
+ let cHash = cTarget.hash ? cTarget.hash.join(Constant.Dot) : Constant.Empty;
60
60
  tokens.push(cTarget.id);
61
61
  tokens.push(entry.data.x);
62
62
  tokens.push(entry.data.y);
@@ -76,9 +76,9 @@ export default async function (type: Event, ts: number = null): Promise<void> {
76
76
  click.reset();
77
77
  break;
78
78
  case Event.Clipboard:
79
- for (const entry of clipboard.state) {
79
+ for (let entry of clipboard.state) {
80
80
  tokens = [entry.time, entry.event];
81
- const target = metadata(entry.data.target as Node, entry.event);
81
+ let target = metadata(entry.data.target as Node, entry.event);
82
82
  if (target.id > 0) {
83
83
  tokens.push(target.id);
84
84
  tokens.push(entry.data.action);
@@ -87,26 +87,24 @@ export default async function (type: Event, ts: number = null): Promise<void> {
87
87
  }
88
88
  clipboard.reset();
89
89
  break;
90
- case Event.Resize: {
91
- const r = resize.data;
90
+ case Event.Resize:
91
+ let r = resize.data;
92
92
  tokens.push(r.width);
93
93
  tokens.push(r.height);
94
94
  baseline.track(type, r.width, r.height);
95
95
  resize.reset();
96
96
  queue(tokens);
97
97
  break;
98
- }
99
- case Event.Unload: {
100
- const u = unload.data;
98
+ case Event.Unload:
99
+ let u = unload.data;
101
100
  tokens.push(u.name);
102
101
  tokens.push(u.persisted);
103
102
  unload.reset();
104
103
  queue(tokens);
105
104
  break;
106
- }
107
105
  case Event.Input:
108
- for (const entry of input.state) {
109
- const iTarget = metadata(entry.data.target as Node, entry.event, entry.data.value);
106
+ for (let entry of input.state) {
107
+ let iTarget = metadata(entry.data.target as Node, entry.event, entry.data.value);
110
108
  tokens = [entry.time, entry.event];
111
109
  tokens.push(iTarget.id);
112
110
  tokens.push(scrub.text(entry.data.value, "input", iTarget.privacy, false, entry.data.type));
@@ -114,11 +112,11 @@ export default async function (type: Event, ts: number = null): Promise<void> {
114
112
  }
115
113
  input.reset();
116
114
  break;
117
- case Event.Selection: {
118
- const s = selection.data;
115
+ case Event.Selection:
116
+ let s = selection.data;
119
117
  if (s) {
120
- const startTarget = metadata(s.start as Node, type);
121
- const endTarget = metadata(s.end as Node, type);
118
+ let startTarget = metadata(s.start as Node, type);
119
+ let endTarget = metadata(s.end as Node, type);
122
120
  tokens.push(startTarget.id);
123
121
  tokens.push(s.startOffset);
124
122
  tokens.push(endTarget.id);
@@ -127,10 +125,9 @@ export default async function (type: Event, ts: number = null): Promise<void> {
127
125
  queue(tokens);
128
126
  }
129
127
  break;
130
- }
131
128
  case Event.Scroll:
132
- for (const entry of scroll.state) {
133
- const sTarget = metadata(entry.data.target as Node, entry.event);
129
+ for (let entry of scroll.state) {
130
+ let sTarget = metadata(entry.data.target as Node, entry.event);
134
131
  const top = metadata(entry.data.top as Node, entry.event);
135
132
  const bottom = metadata(entry.data.bottom as Node, entry.event);
136
133
  const sTopHash = top?.hash ? top.hash.join(Constant.Dot) : Constant.Empty;
@@ -149,9 +146,9 @@ export default async function (type: Event, ts: number = null): Promise<void> {
149
146
  scroll.reset();
150
147
  break;
151
148
  case Event.Change:
152
- for (const entry of change.state) {
149
+ for (let entry of change.state) {
153
150
  tokens = [entry.time, entry.event];
154
- const target = metadata(entry.data.target as Node, entry.event);
151
+ let target = metadata(entry.data.target as Node, entry.event);
155
152
  if (target.id > 0) {
156
153
  tokens = [entry.time, entry.event];
157
154
  tokens.push(target.id);
@@ -164,9 +161,9 @@ export default async function (type: Event, ts: number = null): Promise<void> {
164
161
  change.reset();
165
162
  break;
166
163
  case Event.Submit:
167
- for (const entry of submit.state) {
164
+ for (let entry of submit.state) {
168
165
  tokens = [entry.time, entry.event];
169
- const target = metadata(entry.data.target as Node, entry.event);
166
+ let target = metadata(entry.data.target as Node, entry.event);
170
167
  if (target.id > 0) {
171
168
  tokens.push(target.id);
172
169
  queue(tokens);
@@ -175,7 +172,7 @@ export default async function (type: Event, ts: number = null): Promise<void> {
175
172
  submit.reset();
176
173
  break;
177
174
  case Event.Timeline:
178
- for (const entry of timeline.updates) {
175
+ for (let entry of timeline.updates) {
179
176
  tokens = [entry.time, entry.event];
180
177
  tokens.push(entry.data.type);
181
178
  tokens.push(entry.data.hash);
@@ -187,13 +184,12 @@ export default async function (type: Event, ts: number = null): Promise<void> {
187
184
  }
188
185
  timeline.reset();
189
186
  break;
190
- case Event.Visibility: {
191
- const v = visibility.data;
187
+ case Event.Visibility:
188
+ let v = visibility.data;
192
189
  tokens.push(v.visible);
193
190
  queue(tokens);
194
191
  baseline.visibility(t, v.visible);
195
192
  visibility.reset();
196
193
  break;
197
- }
198
194
  }
199
195
  }
@@ -1,13 +1,13 @@
1
1
  import { Event } from "@clarity-types/data";
2
- import { type InputData, type InputState, Setting } from "@clarity-types/interaction";
2
+ import { InputData, InputState, Setting } from "@clarity-types/interaction";
3
3
  import { FunctionNames } from "@clarity-types/performance";
4
4
  import { bind } from "@src/core/event";
5
5
  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 { get } from "@src/layout/dom";
9
- import { target } from "@src/layout/target";
10
9
  import encode from "./encode";
10
+ import { target } from "@src/layout/target";
11
11
 
12
12
  let timeout: number = null;
13
13
  export let state: InputState[] = [];
@@ -22,11 +22,11 @@ export function observe(root: Node): void {
22
22
 
23
23
  function recompute(evt: UIEvent): void {
24
24
  recompute.dn = FunctionNames.InputRecompute;
25
- const input = target(evt) as HTMLInputElement;
26
- const value = get(input);
27
- if (input?.type && value) {
25
+ let input = target(evt) as HTMLInputElement;
26
+ let value = get(input);
27
+ if (input && input.type && value) {
28
28
  let v = input.value;
29
- const t = input.type;
29
+ let t = input.type;
30
30
  switch (input.type) {
31
31
  case "radio":
32
32
  case "checkbox":
@@ -34,12 +34,10 @@ function recompute(evt: UIEvent): void {
34
34
  break;
35
35
  }
36
36
 
37
- const data: InputData = { target: input, value: v, type: t };
37
+ let data: InputData = { target: input, value: v, type: t };
38
38
 
39
39
  // If last entry in the queue is for the same target node as the current one, remove it so we can later swap it with current data.
40
- if (state.length > 0 && state[state.length - 1].data.target === data.target) {
41
- state.pop();
42
- }
40
+ if (state.length > 0 && (state[state.length - 1].data.target === data.target)) { state.pop(); }
43
41
 
44
42
  state.push({ time: time(evt), event: Event.Input, data });
45
43
 
@@ -59,4 +57,4 @@ export function reset(): void {
59
57
  export function stop(): void {
60
58
  clearTimeout(timeout);
61
59
  reset();
62
- }
60
+ }
@@ -1,5 +1,5 @@
1
1
  import { Event } from "@clarity-types/data";
2
- import { type PointerState, Setting } from "@clarity-types/interaction";
2
+ import { PointerState, Setting } from "@clarity-types/interaction";
3
3
  import { FunctionNames } from "@clarity-types/performance";
4
4
  import { bind } from "@src/core/event";
5
5
  import { schedule } from "@src/core/task";
@@ -34,47 +34,45 @@ export function observe(root: Node): void {
34
34
 
35
35
  function mouse(event: Event, root: Node, evt: MouseEvent): void {
36
36
  mouse.dn = FunctionNames.PointerMouse;
37
- const frame = iframe(root);
38
- const d = frame ? frame.contentDocument.documentElement : document.documentElement;
39
- let x = "pageX" in evt ? Math.round(evt.pageX) : "clientX" in evt ? Math.round((evt as MouseEvent).clientX + d.scrollLeft) : null;
40
- let y = "pageY" in evt ? Math.round(evt.pageY) : "clientY" in evt ? Math.round((evt as MouseEvent).clientY + d.scrollTop) : null;
37
+ let frame = iframe(root);
38
+ let d = frame ? frame.contentDocument.documentElement : document.documentElement;
39
+ let x = "pageX" in evt ? Math.round(evt.pageX) : ("clientX" in evt ? Math.round(evt["clientX"] + d.scrollLeft) : null);
40
+ let y = "pageY" in evt ? Math.round(evt.pageY) : ("clientY" in evt ? Math.round(evt["clientY"] + d.scrollTop) : null);
41
41
  // In case of iframe, we adjust (x,y) to be relative to top parent's origin
42
42
  if (frame) {
43
- const distance = offset(frame);
43
+ let distance = offset(frame);
44
44
  x = x ? x + Math.round(distance.x) : x;
45
45
  y = y ? y + Math.round(distance.y) : y;
46
46
  }
47
47
 
48
48
  // Check for null values before processing this event
49
- if (x !== null && y !== null) {
50
- handler({ time: time(evt), event, data: { target: target(evt), x, y } });
51
- }
49
+ if (x !== null && y !== null) { handler({ time: time(evt), event, data: { target: target(evt), x, y } }); }
52
50
  }
53
51
 
54
52
  function touch(event: Event, root: Node, evt: TouchEvent): void {
55
53
  touch.dn = FunctionNames.PointerTouch;
56
- const frame = iframe(root);
57
- const d = frame ? frame.contentDocument.documentElement : document.documentElement;
58
- const touches = evt.changedTouches;
54
+ let frame = iframe(root);
55
+ let d = frame ? frame.contentDocument.documentElement : document.documentElement;
56
+ let touches = evt.changedTouches;
59
57
 
60
- const t = time(evt);
58
+ let t = time(evt);
61
59
  if (touches) {
62
60
  for (let i = 0; i < touches.length; i++) {
63
- const entry = touches[i];
64
- let x = "clientX" in entry ? Math.round(entry.clientX + d.scrollLeft) : null;
65
- let y = "clientY" in entry ? Math.round(entry.clientY + d.scrollTop) : null;
61
+ let entry = touches[i];
62
+ let x = "clientX" in entry ? Math.round(entry["clientX"] + d.scrollLeft) : null;
63
+ let y = "clientY" in entry ? Math.round(entry["clientY"] + d.scrollTop) : null;
66
64
  x = x && frame ? x + Math.round(frame.offsetLeft) : x;
67
65
  y = y && frame ? y + Math.round(frame.offsetTop) : y;
68
66
 
69
67
  // We cannot rely on identifier to determine primary touch as its value doesn't always start with 0.
70
68
  // Safari/Webkit uses the address of the UITouch object as the identifier value for each touch point.
71
- const id = "identifier" in entry ? entry.identifier : undefined;
69
+ const id = "identifier" in entry ? entry["identifier"] : undefined;
72
70
 
73
- switch (event) {
71
+ switch(event) {
74
72
  case Event.TouchStart:
75
73
  if (activeTouchPointIds.size === 0) {
76
74
  // Track presence of primary touch separately to handle scenarios when same id is repeated
77
- hasPrimaryTouch = true;
75
+ hasPrimaryTouch = true;
78
76
  primaryTouchId = id;
79
77
  }
80
78
  activeTouchPointIds.add(id);
@@ -87,15 +85,11 @@ function touch(event: Event, root: Node, evt: TouchEvent): void {
87
85
  const isPrimary = hasPrimaryTouch && primaryTouchId === id;
88
86
 
89
87
  // Check for null values before processing this event
90
- if (x !== null && y !== null) {
91
- handler({ time: t, event, data: { target: target(evt), x, y, id, isPrimary } });
92
- }
88
+ if (x !== null && y !== null) { handler({ time: t, event, data: { target: target(evt), x, y, id, isPrimary } }); }
93
89
 
94
90
  // Reset primary touch point id once touch event ends
95
91
  if (event === Event.TouchCancel || event === Event.TouchEnd) {
96
- if (primaryTouchId === id) {
97
- hasPrimaryTouch = false;
98
- }
92
+ if (primaryTouchId === id) { hasPrimaryTouch = false; }
99
93
  }
100
94
  }
101
95
  }
@@ -105,18 +99,15 @@ function handler(current: PointerState): void {
105
99
  switch (current.event) {
106
100
  case Event.MouseMove:
107
101
  case Event.MouseWheel:
108
- case Event.TouchMove: {
109
- const length = state.length;
110
- const last = length > 1 ? state[length - 2] : null;
111
- if (last && similar(last, current)) {
112
- state.pop();
113
- }
102
+ case Event.TouchMove:
103
+ let length = state.length;
104
+ let last = length > 1 ? state[length - 2] : null;
105
+ if (last && similar(last, current)) { state.pop(); }
114
106
  state.push(current);
115
107
 
116
108
  clearTimeout(timeout);
117
109
  timeout = setTimeout(process, Setting.LookAhead, current.event);
118
110
  break;
119
- }
120
111
  default:
121
112
  state.push(current);
122
113
  process(current.event);
@@ -145,7 +136,5 @@ function similar(last: PointerState, current: PointerState): boolean {
145
136
  export function stop(): void {
146
137
  clearTimeout(timeout);
147
138
  // Send out any pending pointer events in the pipeline
148
- if (state.length > 0) {
149
- process(state[state.length - 1].event);
150
- }
139
+ if (state.length > 0) { process(state[state.length - 1].event); }
151
140
  }
@@ -1,10 +1,10 @@
1
1
  import { Event } from "@clarity-types/data";
2
- import { type ResizeData, Setting } from "@clarity-types/interaction";
2
+ import { ResizeData, Setting } from "@clarity-types/interaction";
3
3
  import { FunctionNames } from "@clarity-types/performance";
4
- import { bind } from "@src/core/event";
5
- import { schedule } from "@src/core/task";
6
4
  import { clearTimeout, setTimeout } from "@src/core/timeout";
5
+ import { bind } from "@src/core/event";
7
6
  import encode from "./encode";
7
+ import { schedule } from "@src/core/task";
8
8
 
9
9
  export let data: ResizeData;
10
10
  let timeout: number = null;
@@ -18,7 +18,7 @@ export function start(): void {
18
18
 
19
19
  function recompute(): void {
20
20
  recompute.dn = FunctionNames.ResizeRecompute;
21
- const de = document.documentElement;
21
+ let de = document.documentElement;
22
22
  // window.innerWidth includes width of the scrollbar and is not a true representation of the viewport width.
23
23
  // Therefore, when possible, use documentElement's clientWidth property.
24
24
  data = {
@@ -45,4 +45,4 @@ export function reset(): void {
45
45
 
46
46
  export function stop(): void {
47
47
  reset();
48
- }
48
+ }
@@ -1,5 +1,5 @@
1
1
  import { Constant, Dimension, Event } from "@clarity-types/data";
2
- import { type ScrollState, Setting } from "@clarity-types/interaction";
2
+ import { ScrollState, Setting } from "@clarity-types/interaction";
3
3
  import { FunctionNames } from "@clarity-types/performance";
4
4
  import { bind } from "@src/core/event";
5
5
  import { schedule } from "@src/core/task";
@@ -8,7 +8,7 @@ import { clearTimeout, setTimeout } from "@src/core/timeout";
8
8
  import throttle from "@src/core/throttle";
9
9
  import * as dimension from "@src/data/dimension";
10
10
  import { iframe } from "@src/layout/dom";
11
- import { metadata, target } from "@src/layout/target";
11
+ import { target, metadata } from "@src/layout/target";
12
12
  import encode from "./encode";
13
13
 
14
14
  export let state: ScrollState[] = [];
@@ -35,7 +35,7 @@ function recompute(event: UIEvent = null): void {
35
35
 
36
36
  // If the target is a Document node, then identify corresponding documentElement and window for this document
37
37
  if (element && element.nodeType === Node.DOCUMENT_NODE) {
38
- const frame = iframe(element);
38
+ let frame = iframe(element);
39
39
  w = frame ? frame.contentWindow : w;
40
40
  element = de = (element as Document).documentElement;
41
41
  }
@@ -43,8 +43,8 @@ function recompute(event: UIEvent = null): void {
43
43
  // Edge doesn't support scrollTop position on document.documentElement.
44
44
  // For cross browser compatibility, looking up pageYOffset on window if the scroll is on document.
45
45
  // And, if for some reason that is not available, fall back to looking up scrollTop on document.documentElement.
46
- const x = element === de && "pageXOffset" in w ? Math.round(w.pageXOffset) : Math.round((element as HTMLElement).scrollLeft);
47
- const y = element === de && "pageYOffset" in w ? Math.round(w.pageYOffset) : Math.round((element as HTMLElement).scrollTop);
46
+ let x = element === de && "pageXOffset" in w ? Math.round(w.pageXOffset) : Math.round((element as HTMLElement).scrollLeft);
47
+ let y = element === de && "pageYOffset" in w ? Math.round(w.pageYOffset) : Math.round((element as HTMLElement).scrollTop);
48
48
  const width = window.innerWidth;
49
49
  const height = window.innerHeight;
50
50
  const xPosition = width / 3;
@@ -54,20 +54,18 @@ function recompute(event: UIEvent = null): void {
54
54
  const top = getPositionNode(xPosition, startYPosition);
55
55
  const bottom = getPositionNode(xPosition, endYPosition);
56
56
 
57
- const current: ScrollState = { time: time(event), event: Event.Scroll, data: { target: element, x, y, top, bottom } };
57
+ let current: ScrollState = { time: time(event), event: Event.Scroll, data: {target: element, x, y, top, bottom} };
58
58
 
59
59
  // We don't send any scroll events if this is the first event and the current position is top (0,0)
60
- if ((event === null && x === 0 && y === 0) || x === null || y === null) {
60
+ if ((event === null && x === 0 && y === 0) || (x === null || y === null)) {
61
61
  initialTop = top;
62
62
  initialBottom = bottom;
63
63
  return;
64
64
  }
65
65
 
66
- const length = state.length;
67
- const last = length > 1 ? state[length - 2] : null;
68
- if (last && similar(last, current)) {
69
- state.pop();
70
- }
66
+ let length = state.length;
67
+ let last = length > 1 ? state[length - 2] : null;
68
+ if (last && similar(last, current)) { state.pop(); }
71
69
  state.push(current);
72
70
 
73
71
  clearTimeout(timeout);
@@ -79,10 +77,9 @@ const throttledRecompute = throttle(recompute, Setting.Throttle);
79
77
  function getPositionNode(x: number, y: number): Node {
80
78
  let node: Node;
81
79
  if ("caretPositionFromPoint" in document) {
82
- // biome-ignore lint/suspicious/noExplicitAny: caretPositionFromPoint is not defined on all browsers, makes typescript unhappy
83
80
  node = (document as any).caretPositionFromPoint(x, y)?.offsetNode;
84
81
  } else if ("caretRangeFromPoint" in document) {
85
- node = (document as Document).caretRangeFromPoint(x, y)?.startContainer;
82
+ node = (document as any).caretRangeFromPoint(x, y)?.startContainer;
86
83
  }
87
84
  if (!node) {
88
85
  node = document.elementFromPoint(x, y) as Node;
@@ -1,5 +1,5 @@
1
1
  import { Event } from "@clarity-types/data";
2
- import { type SelectionData, Setting } from "@clarity-types/interaction";
2
+ import { SelectionData, Setting } from "@clarity-types/interaction";
3
3
  import { FunctionNames } from "@clarity-types/performance";
4
4
  import { bind } from "@src/core/event";
5
5
  import { schedule } from "@src/core/task";
@@ -21,25 +21,21 @@ export function observe(root: Node): void {
21
21
 
22
22
  function recompute(root: Node): void {
23
23
  recompute.dn = FunctionNames.SelectionRecompute;
24
- const doc = root.nodeType === Node.DOCUMENT_NODE ? (root as Document) : document;
25
- const current = doc.getSelection();
24
+ let doc = root.nodeType === Node.DOCUMENT_NODE ? root as Document : document;
25
+ let current = doc.getSelection();
26
26
 
27
27
  // Bail out if we don't have a valid selection
28
- if (current === null) {
29
- return;
30
- }
28
+ if (current === null) { return; }
31
29
 
32
30
  // Bail out if we got a valid selection but not valid nodes
33
31
  // In Edge, selectionchange gets fired even on interactions like right clicks and
34
32
  // can result in null anchorNode and focusNode if there was no previous selection on page
35
33
  // Also, ignore any selections that start and end at the exact same point
36
- if (
37
- (current.anchorNode === null && current.focusNode === null) ||
38
- (current.anchorNode === current.focusNode && current.anchorOffset === current.focusOffset)
39
- ) {
34
+ if ((current.anchorNode === null && current.focusNode === null) ||
35
+ (current.anchorNode === current.focusNode && current.anchorOffset === current.focusOffset)) {
40
36
  return;
41
37
  }
42
- const startNode = data.start ? data.start : null;
38
+ let startNode = data.start ? data.start : null;
43
39
  if (previous !== null && data.start !== null && startNode !== current.anchorNode) {
44
40
  clearTimeout(timeout);
45
41
  process(Event.Selection);
@@ -49,7 +45,7 @@ function recompute(root: Node): void {
49
45
  start: current.anchorNode,
50
46
  startOffset: current.anchorOffset,
51
47
  end: current.focusNode,
52
- endOffset: current.focusOffset,
48
+ endOffset: current.focusOffset
53
49
  };
54
50
  previous = current;
55
51
 
@@ -1,11 +1,11 @@
1
1
  import { Event } from "@clarity-types/data";
2
- import type { SubmitState } from "@clarity-types/interaction";
2
+ import { SubmitState } from "@clarity-types/interaction";
3
3
  import { FunctionNames } from "@clarity-types/performance";
4
4
  import { bind } from "@src/core/event";
5
5
  import { schedule } from "@src/core/task";
6
6
  import { time } from "@src/core/time";
7
- import { target } from "@src/layout/target";
8
7
  import encode from "./encode";
8
+ import { target } from "@src/layout/target";
9
9
 
10
10
  export let state: SubmitState[] = [];
11
11
 
@@ -1,5 +1,5 @@
1
1
  import { BooleanFlag, Event } from "@clarity-types/data";
2
- import { BrowsingContext, Setting, type TimelineState } from "@clarity-types/interaction";
2
+ import { BrowsingContext, Setting, TimelineState } from "@clarity-types/interaction";
3
3
  import * as baseline from "@src/data/baseline";
4
4
  import * as envelope from "@src/data/envelope";
5
5
  import encode from "@src/interaction/encode";
@@ -16,15 +16,13 @@ export function reset(): void {
16
16
  updates = [];
17
17
  }
18
18
 
19
- export function track(
20
- time: number,
19
+ export function track(time: number,
21
20
  event: Event,
22
21
  hash: string,
23
22
  x: number,
24
23
  y: number,
25
24
  reaction: number = BooleanFlag.True,
26
- context: number = BrowsingContext.Self,
27
- ): void {
25
+ context: number = BrowsingContext.Self): void {
28
26
  state.push({
29
27
  time,
30
28
  event: Event.Timeline,
@@ -34,8 +32,8 @@ export function track(
34
32
  x,
35
33
  y,
36
34
  reaction,
37
- context,
38
- },
35
+ context
36
+ }
39
37
  });
40
38
 
41
39
  // Since timeline only keeps the data for configured time, we still want to continue tracking these values
@@ -47,14 +45,12 @@ export function track(
47
45
  export function compute(): void {
48
46
  const temp = [];
49
47
  updates = [];
50
- const max = envelope.data.start + envelope.data.duration;
51
- const min = Math.max(max - Setting.TimelineSpan, 0);
48
+ let max = envelope.data.start + envelope.data.duration;
49
+ let min = Math.max(max - Setting.TimelineSpan, 0);
52
50
 
53
- for (const s of state) {
51
+ for (let s of state) {
54
52
  if (s.time >= min) {
55
- if (s.time <= max) {
56
- updates.push(s);
57
- }
53
+ if (s.time <= max) { updates.push(s); }
58
54
  temp.push(s);
59
55
  }
60
56
  }
@@ -1,5 +1,5 @@
1
1
  import { BooleanFlag, Event } from "@clarity-types/data";
2
- import type { UnloadData } from "@clarity-types/interaction";
2
+ import { UnloadData } from "@clarity-types/interaction";
3
3
  import { FunctionNames } from "@clarity-types/performance";
4
4
  import * as clarity from "@src/clarity";
5
5
  import { bind } from "@src/core/event";
@@ -1,5 +1,5 @@
1
1
  import { Event } from "@clarity-types/data";
2
- import type { VisibilityData } from "@clarity-types/interaction";
2
+ import { VisibilityData } from "@clarity-types/interaction";
3
3
  import { FunctionNames } from "@clarity-types/performance";
4
4
  import { bind } from "@src/core/event";
5
5
  import { time } from "@src/core/time";
@@ -24,4 +24,4 @@ export function reset(): void {
24
24
 
25
25
  export function stop(): void {
26
26
  reset();
27
- }
27
+ }