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.
- package/build/clarity.extended.js +1 -1
- package/build/clarity.insight.js +1 -1
- package/build/clarity.js +16 -7
- package/build/clarity.min.js +1 -1
- package/build/clarity.module.js +16 -7
- package/build/clarity.performance.js +1 -1
- package/package.json +1 -1
- package/src/core/report.ts +3 -7
- package/src/core/scrub.ts +7 -1
- package/src/core/version.ts +1 -1
- package/src/data/metadata.ts +8 -0
- package/src/interaction/pointer.ts +6 -6
- package/src/interaction/scroll.ts +6 -6
- package/src/layout/region.ts +3 -6
- package/src/layout/style.ts +1 -1
- package/types/data.d.ts +2 -1
- package/types/interaction.d.ts +0 -1
package/src/core/report.ts
CHANGED
|
@@ -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
|
-
|
|
17
|
-
if (e.message) {
|
|
18
|
-
|
|
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
|
-
|
|
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":
|
package/src/core/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
let version = "0.8.
|
|
1
|
+
let version = "0.8.15";
|
|
2
2
|
export default version;
|
package/src/data/metadata.ts
CHANGED
|
@@ -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
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
-
|
|
26
|
-
|
|
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
|
-
|
|
106
|
-
|
|
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 {
|
package/src/layout/region.ts
CHANGED
|
@@ -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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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;
|
package/src/layout/style.ts
CHANGED
package/types/data.d.ts
CHANGED
package/types/interaction.d.ts
CHANGED
|
@@ -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
|
|