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.
@@ -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
  }
@@ -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
@@ -140,6 +140,7 @@ export interface Config {
140
140
  throttleDom?: boolean;
141
141
  conversions?: boolean;
142
142
  includeSubdomains?: boolean;
143
+ modules?: string[];
143
144
  }
144
145
 
145
146
  export const enum Constant {
package/types/data.d.ts CHANGED
@@ -212,6 +212,7 @@ export const enum Code {
212
212
  Config = 8,
213
213
  FunctionExecutionTime = 9,
214
214
  LeanLimit = 10,
215
+ BFCache = 11,
215
216
  }
216
217
 
217
218
  export const enum Severity {
@@ -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 {