clarity-js 0.8.48 → 0.8.50-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.
- package/build/clarity.extended.js +1 -1
- package/build/clarity.insight.js +1 -1
- package/build/clarity.js +98 -44
- package/build/clarity.min.js +1 -1
- package/build/clarity.module.js +98 -44
- package/build/clarity.performance.js +1 -1
- package/package.json +1 -1
- package/src/core/config.ts +1 -0
- package/src/core/dynamic.ts +7 -2
- package/src/core/version.ts +1 -1
- package/src/interaction/click.ts +24 -1
- package/src/interaction/encode.ts +2 -0
- package/src/interaction/index.ts +3 -0
- package/src/interaction/pageshow.ts +35 -0
- package/src/interaction/scroll.ts +3 -2
- package/types/core.d.ts +1 -0
- package/types/data.d.ts +1 -0
- package/types/interaction.d.ts +10 -0
package/src/interaction/click.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BooleanFlag, Constant, Event, Setting } from "@clarity-types/data";
|
|
2
|
-
import { BrowsingContext, ClickState, TextInfo } from "@clarity-types/interaction";
|
|
2
|
+
import { BrowsingContext, ClickSource, ClickState, TextInfo } from "@clarity-types/interaction";
|
|
3
3
|
import { Box } from "@clarity-types/layout";
|
|
4
4
|
import { bind } from "@src/core/event";
|
|
5
5
|
import { schedule } from "@src/core/task";
|
|
@@ -75,6 +75,7 @@ function handler(event: Event, root: Node, evt: MouseEvent): void {
|
|
|
75
75
|
tag: getElementAttribute(t, "tagName").substring(0, Setting.ClickTag),
|
|
76
76
|
class: getElementAttribute(t, "className").substring(0, Setting.ClickClass),
|
|
77
77
|
id: getElementAttribute(t, "id").substring(0, Setting.ClickId),
|
|
78
|
+
source: evt.isTrusted ? ClickSource.Undefined : source()
|
|
78
79
|
}
|
|
79
80
|
});
|
|
80
81
|
schedule(encode.bind(this, event));
|
|
@@ -164,6 +165,28 @@ function context(a: HTMLAnchorElement): BrowsingContext {
|
|
|
164
165
|
return BrowsingContext.Self;
|
|
165
166
|
}
|
|
166
167
|
|
|
168
|
+
function source(): ClickSource {
|
|
169
|
+
try {
|
|
170
|
+
const stack = new Error().stack || "";
|
|
171
|
+
const origin = location.origin;
|
|
172
|
+
let result = ClickSource.Unknown;
|
|
173
|
+
|
|
174
|
+
for (const line of stack.split("\n")) {
|
|
175
|
+
if (line.indexOf("://") >= 0) {
|
|
176
|
+
result = line.indexOf("extension") < 0 && line.indexOf(origin) >= 0
|
|
177
|
+
? ClickSource.FirstParty
|
|
178
|
+
: ClickSource.ThirdParty;
|
|
179
|
+
} else if (line.indexOf("eval") >= 0 || line.indexOf("Function") >= 0 || line.indexOf("<a") >= 0 || /VM\d/.test(line)) {
|
|
180
|
+
result = ClickSource.Eval;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return result;
|
|
185
|
+
} catch {
|
|
186
|
+
return ClickSource.Unknown;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
167
190
|
export function reset(): void {
|
|
168
191
|
state = [];
|
|
169
192
|
}
|
|
@@ -77,6 +77,7 @@ export default async function (type: Event, ts: number = null): Promise<void> {
|
|
|
77
77
|
tokens.push(entry.data.tag);
|
|
78
78
|
tokens.push(entry.data.class);
|
|
79
79
|
tokens.push(entry.data.id);
|
|
80
|
+
tokens.push(entry.data.source);
|
|
80
81
|
queue(tokens);
|
|
81
82
|
timeline.track(entry.time, entry.event, cHash, entry.data.x, entry.data.y, entry.data.reaction, entry.data.context);
|
|
82
83
|
}
|
|
@@ -147,6 +148,7 @@ export default async function (type: Event, ts: number = null): Promise<void> {
|
|
|
147
148
|
tokens.push(entry.data.y);
|
|
148
149
|
tokens.push(sTopHash);
|
|
149
150
|
tokens.push(sBottomHash);
|
|
151
|
+
tokens.push(entry.data.trust);
|
|
150
152
|
queue(tokens);
|
|
151
153
|
baseline.track(entry.event, entry.data.x, entry.data.y, entry.time);
|
|
152
154
|
}
|
package/src/interaction/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ import * as timeline from "@src/interaction/timeline";
|
|
|
11
11
|
import * as unload from "@src/interaction/unload";
|
|
12
12
|
import * as visibility from "@src/interaction/visibility";
|
|
13
13
|
import * as focus from "@src/interaction/focus";
|
|
14
|
+
import * as pageshow from "@src/interaction/pageshow";
|
|
14
15
|
|
|
15
16
|
export function start(): void {
|
|
16
17
|
timeline.start();
|
|
@@ -21,6 +22,7 @@ export function start(): void {
|
|
|
21
22
|
resize.start();
|
|
22
23
|
visibility.start();
|
|
23
24
|
focus.start();
|
|
25
|
+
pageshow.start();
|
|
24
26
|
scroll.start();
|
|
25
27
|
selection.start();
|
|
26
28
|
change.start();
|
|
@@ -37,6 +39,7 @@ export function stop(): void {
|
|
|
37
39
|
resize.stop();
|
|
38
40
|
visibility.stop();
|
|
39
41
|
focus.stop();
|
|
42
|
+
pageshow.stop();
|
|
40
43
|
scroll.stop();
|
|
41
44
|
selection.stop();
|
|
42
45
|
change.stop();
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Constant } from "@clarity-types/core";
|
|
2
|
+
import { Code, Severity } from "@clarity-types/data";
|
|
3
|
+
import * as clarity from "@src/clarity";
|
|
4
|
+
import api from "@src/core/api";
|
|
5
|
+
import measure from "@src/core/measure";
|
|
6
|
+
import * as internal from "@src/diagnostic/internal";
|
|
7
|
+
|
|
8
|
+
let bound = false;
|
|
9
|
+
|
|
10
|
+
export function start(): void {
|
|
11
|
+
// Only bind once - this listener must persist even when Clarity stops
|
|
12
|
+
// to detect when the page is restored from bfcache
|
|
13
|
+
if (!bound) {
|
|
14
|
+
try {
|
|
15
|
+
window[api(Constant.AddEventListener)]("pageshow", measure(handler) as EventListener, { capture: false, passive: true });
|
|
16
|
+
bound = true;
|
|
17
|
+
} catch {
|
|
18
|
+
/* do nothing */
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function handler(evt: PageTransitionEvent): void {
|
|
24
|
+
// The persisted property indicates if the page was loaded from bfcache
|
|
25
|
+
if (evt && evt.persisted) {
|
|
26
|
+
// Restart Clarity since it was stopped when the page entered bfcache
|
|
27
|
+
clarity.start();
|
|
28
|
+
internal.log(Code.BFCache, Severity.Info);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function stop(): void {
|
|
33
|
+
// Intentionally don't remove the listener or reset 'bound' flag
|
|
34
|
+
// We need the listener to persist to detect bfcache restoration
|
|
35
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Constant, Dimension, Event } from "@clarity-types/data";
|
|
1
|
+
import { BooleanFlag, Constant, Dimension, Event } from "@clarity-types/data";
|
|
2
2
|
import { ScrollState, Setting } from "@clarity-types/interaction";
|
|
3
3
|
import { bind } from "@src/core/event";
|
|
4
4
|
import { schedule } from "@src/core/task";
|
|
@@ -55,8 +55,9 @@ function recompute(event: UIEvent = null): void {
|
|
|
55
55
|
const endYPosition = height - yOffset;
|
|
56
56
|
const top = getPositionNode(xPosition, startYPosition);
|
|
57
57
|
const bottom = getPositionNode(xPosition, endYPosition);
|
|
58
|
+
const trust = event && event.isTrusted ? BooleanFlag.True : BooleanFlag.False;
|
|
58
59
|
|
|
59
|
-
let current: ScrollState = { time: time(event), event: Event.Scroll, data: {target: element, x, y, top, bottom} };
|
|
60
|
+
let current: ScrollState = { time: time(event), event: Event.Scroll, data: {target: element, x, y, top, bottom, trust} };
|
|
60
61
|
|
|
61
62
|
// We don't send any scroll events if this is the first event and the current position is top (0,0)
|
|
62
63
|
if ((event === null && x === 0 && y === 0) || (x === null || y === null)) {
|
package/types/core.d.ts
CHANGED
package/types/data.d.ts
CHANGED
package/types/interaction.d.ts
CHANGED
|
@@ -11,6 +11,14 @@ export const enum BrowsingContext {
|
|
|
11
11
|
Top = 3
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
export const enum ClickSource {
|
|
15
|
+
Undefined = 0,
|
|
16
|
+
FirstParty = 1,
|
|
17
|
+
ThirdParty = 2,
|
|
18
|
+
Eval = 3,
|
|
19
|
+
Unknown = 4
|
|
20
|
+
}
|
|
21
|
+
|
|
14
22
|
export const enum Setting {
|
|
15
23
|
LookAhead = 500, // 500ms
|
|
16
24
|
InputLookAhead = 1000, // 1s
|
|
@@ -131,6 +139,7 @@ export interface ClickData {
|
|
|
131
139
|
tag: string;
|
|
132
140
|
class: string;
|
|
133
141
|
id: string;
|
|
142
|
+
source: ClickSource;
|
|
134
143
|
}
|
|
135
144
|
|
|
136
145
|
export interface TextInfo {
|
|
@@ -154,6 +163,7 @@ export interface ScrollData {
|
|
|
154
163
|
y: number;
|
|
155
164
|
top: Node | string;
|
|
156
165
|
bottom: Node | string;
|
|
166
|
+
trust: BooleanFlag;
|
|
157
167
|
}
|
|
158
168
|
|
|
159
169
|
export interface SelectionData {
|