@openreplay/tracker 5.0.2-beta.1 → 5.0.3
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/cjs/app/index.js +1 -1
- package/cjs/app/nodes.d.ts +1 -0
- package/cjs/app/nodes.js +3 -0
- package/cjs/index.d.ts +2 -0
- package/cjs/index.js +2 -2
- package/cjs/modules/mouse.d.ts +23 -1
- package/cjs/modules/mouse.js +10 -9
- package/lib/app/index.js +1 -1
- package/lib/app/nodes.d.ts +1 -0
- package/lib/app/nodes.js +3 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -2
- package/lib/modules/mouse.d.ts +23 -1
- package/lib/modules/mouse.js +10 -9
- package/package.json +1 -1
package/cjs/app/index.js
CHANGED
|
@@ -33,7 +33,7 @@ class App {
|
|
|
33
33
|
this.stopCallbacks = [];
|
|
34
34
|
this.commitCallbacks = [];
|
|
35
35
|
this.activityState = ActivityState.NotActive;
|
|
36
|
-
this.version = '5.0.
|
|
36
|
+
this.version = '5.0.3'; // TODO: version compatability check inside each plugin.
|
|
37
37
|
this._usingOldFetchPlugin = false;
|
|
38
38
|
this.delay = 0;
|
|
39
39
|
this.projectKey = projectKey;
|
package/cjs/app/nodes.d.ts
CHANGED
package/cjs/app/nodes.js
CHANGED
|
@@ -4,6 +4,7 @@ class Nodes {
|
|
|
4
4
|
constructor(node_id) {
|
|
5
5
|
this.node_id = node_id;
|
|
6
6
|
this.nodes = [];
|
|
7
|
+
this.totalNodeAmount = 0;
|
|
7
8
|
this.nodeCallbacks = [];
|
|
8
9
|
this.elementListeners = new Map();
|
|
9
10
|
}
|
|
@@ -28,6 +29,7 @@ class Nodes {
|
|
|
28
29
|
let id = node[this.node_id];
|
|
29
30
|
const isNew = id === undefined;
|
|
30
31
|
if (isNew) {
|
|
32
|
+
this.totalNodeAmount++;
|
|
31
33
|
id = this.nodes.length;
|
|
32
34
|
this.nodes[id] = node;
|
|
33
35
|
node[this.node_id] = id;
|
|
@@ -44,6 +46,7 @@ class Nodes {
|
|
|
44
46
|
this.elementListeners.delete(id);
|
|
45
47
|
listeners.forEach((listener) => node.removeEventListener(listener[0], listener[1], listener[2]));
|
|
46
48
|
}
|
|
49
|
+
this.totalNodeAmount--;
|
|
47
50
|
}
|
|
48
51
|
return id;
|
|
49
52
|
}
|
package/cjs/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ import type { Options as TimingOptions } from './modules/timing.js';
|
|
|
12
12
|
import type { Options as NetworkOptions } from './modules/network.js';
|
|
13
13
|
import type { StartOptions } from './app/index.js';
|
|
14
14
|
import type { StartPromiseReturn } from './app/index.js';
|
|
15
|
+
import type { MouseHandlerOptions } from './modules/mouse.js';
|
|
15
16
|
export type Options = Partial<AppOptions & ConsoleOptions & ExceptionOptions & InputOptions & PerformanceOptions & TimingOptions> & {
|
|
16
17
|
projectID?: number;
|
|
17
18
|
projectKey: string;
|
|
@@ -19,6 +20,7 @@ export type Options = Partial<AppOptions & ConsoleOptions & ExceptionOptions & I
|
|
|
19
20
|
respectDoNotTrack?: boolean;
|
|
20
21
|
autoResetOnWindowOpen?: boolean;
|
|
21
22
|
network?: NetworkOptions;
|
|
23
|
+
mouse?: MouseHandlerOptions;
|
|
22
24
|
__DISABLE_SECURE_MODE?: boolean;
|
|
23
25
|
};
|
|
24
26
|
export default class API {
|
package/cjs/index.js
CHANGED
|
@@ -109,7 +109,7 @@ class API {
|
|
|
109
109
|
(0, exception_js_1.default)(app, options);
|
|
110
110
|
(0, img_js_1.default)(app);
|
|
111
111
|
(0, input_js_1.default)(app, options);
|
|
112
|
-
(0, mouse_js_1.default)(app);
|
|
112
|
+
(0, mouse_js_1.default)(app, options.mouse);
|
|
113
113
|
(0, timing_js_1.default)(app, options);
|
|
114
114
|
(0, performance_js_1.default)(app, options);
|
|
115
115
|
(0, scroll_js_1.default)(app);
|
|
@@ -140,7 +140,7 @@ class API {
|
|
|
140
140
|
// no-cors issue only with text/plain or not-set Content-Type
|
|
141
141
|
// req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
|
142
142
|
req.send(JSON.stringify({
|
|
143
|
-
trackerVersion: '5.0.
|
|
143
|
+
trackerVersion: '5.0.3',
|
|
144
144
|
projectKey: options.projectKey,
|
|
145
145
|
doNotTrack,
|
|
146
146
|
// TODO: add precise reason (an exact API missing)
|
package/cjs/modules/mouse.d.ts
CHANGED
|
@@ -1,2 +1,24 @@
|
|
|
1
1
|
import type App from '../app/index.js';
|
|
2
|
-
export
|
|
2
|
+
export interface MouseHandlerOptions {
|
|
3
|
+
disableClickmaps?: boolean;
|
|
4
|
+
/** minimum length of an optimised selector.
|
|
5
|
+
*
|
|
6
|
+
* body > div > div > p => body > p for example
|
|
7
|
+
*
|
|
8
|
+
* default 2
|
|
9
|
+
* */
|
|
10
|
+
minSelectorDepth?: number;
|
|
11
|
+
/** how many selectors to try before falling back to nth-child selectors
|
|
12
|
+
* performance expensive operation
|
|
13
|
+
*
|
|
14
|
+
* default 1000
|
|
15
|
+
* */
|
|
16
|
+
nthThreshold?: number;
|
|
17
|
+
/**
|
|
18
|
+
* how many tries to optimise and shorten the selector
|
|
19
|
+
*
|
|
20
|
+
* default 10_000
|
|
21
|
+
* */
|
|
22
|
+
maxOptimiseTries?: number;
|
|
23
|
+
}
|
|
24
|
+
export default function (app: App, options?: MouseHandlerOptions): void;
|
package/cjs/modules/mouse.js
CHANGED
|
@@ -5,13 +5,13 @@ const utils_js_1 = require("../utils.js");
|
|
|
5
5
|
const messages_gen_js_1 = require("../app/messages.gen.js");
|
|
6
6
|
const input_js_1 = require("./input.js");
|
|
7
7
|
const finder_1 = require("@medv/finder");
|
|
8
|
-
function _getSelector(target, document) {
|
|
8
|
+
function _getSelector(target, document, options) {
|
|
9
9
|
const selector = (0, finder_1.finder)(target, {
|
|
10
10
|
root: document.body,
|
|
11
11
|
seedMinLength: 3,
|
|
12
|
-
optimizedMinLength: 2,
|
|
13
|
-
threshold: 1000,
|
|
14
|
-
maxNumberOfTries: 10000,
|
|
12
|
+
optimizedMinLength: (options === null || options === void 0 ? void 0 : options.minSelectorDepth) || 2,
|
|
13
|
+
threshold: (options === null || options === void 0 ? void 0 : options.nthThreshold) || 1000,
|
|
14
|
+
maxNumberOfTries: (options === null || options === void 0 ? void 0 : options.maxOptimiseTries) || 10000,
|
|
15
15
|
});
|
|
16
16
|
return selector;
|
|
17
17
|
}
|
|
@@ -26,7 +26,7 @@ function isClickable(element) {
|
|
|
26
26
|
element.onclick != null ||
|
|
27
27
|
element.getAttribute('role') === 'button');
|
|
28
28
|
//|| element.className.includes("btn")
|
|
29
|
-
// MBTODO:
|
|
29
|
+
// MBTODO: intercept addEventListener
|
|
30
30
|
}
|
|
31
31
|
//TODO: fix (typescript is not sure about target variable after assignation of svg)
|
|
32
32
|
function getTarget(target, document) {
|
|
@@ -66,7 +66,8 @@ function _getTarget(target, document) {
|
|
|
66
66
|
}
|
|
67
67
|
return target === document.documentElement ? null : target;
|
|
68
68
|
}
|
|
69
|
-
function default_1(app) {
|
|
69
|
+
function default_1(app, options) {
|
|
70
|
+
const { disableClickmaps = false } = options || {};
|
|
70
71
|
function getTargetLabel(target) {
|
|
71
72
|
const dl = (0, utils_js_1.getLabelAttribute)(target);
|
|
72
73
|
if (dl !== null) {
|
|
@@ -105,8 +106,8 @@ function default_1(app) {
|
|
|
105
106
|
}
|
|
106
107
|
};
|
|
107
108
|
const patchDocument = (document, topframe = false) => {
|
|
108
|
-
function getSelector(id, target) {
|
|
109
|
-
return (selectorMap[id] = selectorMap[id] || _getSelector(target, document));
|
|
109
|
+
function getSelector(id, target, options) {
|
|
110
|
+
return (selectorMap[id] = selectorMap[id] || _getSelector(target, document, options));
|
|
110
111
|
}
|
|
111
112
|
const attachListener = topframe
|
|
112
113
|
? app.attachEventListener.bind(app) // attached/removed on start/stop
|
|
@@ -132,7 +133,7 @@ function default_1(app) {
|
|
|
132
133
|
const id = app.nodes.getID(target);
|
|
133
134
|
if (id !== undefined) {
|
|
134
135
|
sendMouseMove();
|
|
135
|
-
app.send((0, messages_gen_js_1.MouseClick)(id, mouseTarget === target ? Math.round(performance.now() - mouseTargetTime) : 0, getTargetLabel(target), isClickable(target) ? getSelector(id, target) : ''), true);
|
|
136
|
+
app.send((0, messages_gen_js_1.MouseClick)(id, mouseTarget === target ? Math.round(performance.now() - mouseTargetTime) : 0, getTargetLabel(target), isClickable(target) && !disableClickmaps ? getSelector(id, target, options) : ''), true);
|
|
136
137
|
}
|
|
137
138
|
mouseTarget = null;
|
|
138
139
|
});
|
package/lib/app/index.js
CHANGED
|
@@ -30,7 +30,7 @@ export default class App {
|
|
|
30
30
|
this.stopCallbacks = [];
|
|
31
31
|
this.commitCallbacks = [];
|
|
32
32
|
this.activityState = ActivityState.NotActive;
|
|
33
|
-
this.version = '5.0.
|
|
33
|
+
this.version = '5.0.3'; // TODO: version compatability check inside each plugin.
|
|
34
34
|
this._usingOldFetchPlugin = false;
|
|
35
35
|
this.delay = 0;
|
|
36
36
|
this.projectKey = projectKey;
|
package/lib/app/nodes.d.ts
CHANGED
package/lib/app/nodes.js
CHANGED
|
@@ -2,6 +2,7 @@ export default class Nodes {
|
|
|
2
2
|
constructor(node_id) {
|
|
3
3
|
this.node_id = node_id;
|
|
4
4
|
this.nodes = [];
|
|
5
|
+
this.totalNodeAmount = 0;
|
|
5
6
|
this.nodeCallbacks = [];
|
|
6
7
|
this.elementListeners = new Map();
|
|
7
8
|
}
|
|
@@ -26,6 +27,7 @@ export default class Nodes {
|
|
|
26
27
|
let id = node[this.node_id];
|
|
27
28
|
const isNew = id === undefined;
|
|
28
29
|
if (isNew) {
|
|
30
|
+
this.totalNodeAmount++;
|
|
29
31
|
id = this.nodes.length;
|
|
30
32
|
this.nodes[id] = node;
|
|
31
33
|
node[this.node_id] = id;
|
|
@@ -42,6 +44,7 @@ export default class Nodes {
|
|
|
42
44
|
this.elementListeners.delete(id);
|
|
43
45
|
listeners.forEach((listener) => node.removeEventListener(listener[0], listener[1], listener[2]));
|
|
44
46
|
}
|
|
47
|
+
this.totalNodeAmount--;
|
|
45
48
|
}
|
|
46
49
|
return id;
|
|
47
50
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ import type { Options as TimingOptions } from './modules/timing.js';
|
|
|
12
12
|
import type { Options as NetworkOptions } from './modules/network.js';
|
|
13
13
|
import type { StartOptions } from './app/index.js';
|
|
14
14
|
import type { StartPromiseReturn } from './app/index.js';
|
|
15
|
+
import type { MouseHandlerOptions } from './modules/mouse.js';
|
|
15
16
|
export type Options = Partial<AppOptions & ConsoleOptions & ExceptionOptions & InputOptions & PerformanceOptions & TimingOptions> & {
|
|
16
17
|
projectID?: number;
|
|
17
18
|
projectKey: string;
|
|
@@ -19,6 +20,7 @@ export type Options = Partial<AppOptions & ConsoleOptions & ExceptionOptions & I
|
|
|
19
20
|
respectDoNotTrack?: boolean;
|
|
20
21
|
autoResetOnWindowOpen?: boolean;
|
|
21
22
|
network?: NetworkOptions;
|
|
23
|
+
mouse?: MouseHandlerOptions;
|
|
22
24
|
__DISABLE_SECURE_MODE?: boolean;
|
|
23
25
|
};
|
|
24
26
|
export default class API {
|
package/lib/index.js
CHANGED
|
@@ -104,7 +104,7 @@ export default class API {
|
|
|
104
104
|
Exception(app, options);
|
|
105
105
|
Img(app);
|
|
106
106
|
Input(app, options);
|
|
107
|
-
Mouse(app);
|
|
107
|
+
Mouse(app, options.mouse);
|
|
108
108
|
Timing(app, options);
|
|
109
109
|
Performance(app, options);
|
|
110
110
|
Scroll(app);
|
|
@@ -135,7 +135,7 @@ export default class API {
|
|
|
135
135
|
// no-cors issue only with text/plain or not-set Content-Type
|
|
136
136
|
// req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
|
137
137
|
req.send(JSON.stringify({
|
|
138
|
-
trackerVersion: '5.0.
|
|
138
|
+
trackerVersion: '5.0.3',
|
|
139
139
|
projectKey: options.projectKey,
|
|
140
140
|
doNotTrack,
|
|
141
141
|
// TODO: add precise reason (an exact API missing)
|
package/lib/modules/mouse.d.ts
CHANGED
|
@@ -1,2 +1,24 @@
|
|
|
1
1
|
import type App from '../app/index.js';
|
|
2
|
-
export
|
|
2
|
+
export interface MouseHandlerOptions {
|
|
3
|
+
disableClickmaps?: boolean;
|
|
4
|
+
/** minimum length of an optimised selector.
|
|
5
|
+
*
|
|
6
|
+
* body > div > div > p => body > p for example
|
|
7
|
+
*
|
|
8
|
+
* default 2
|
|
9
|
+
* */
|
|
10
|
+
minSelectorDepth?: number;
|
|
11
|
+
/** how many selectors to try before falling back to nth-child selectors
|
|
12
|
+
* performance expensive operation
|
|
13
|
+
*
|
|
14
|
+
* default 1000
|
|
15
|
+
* */
|
|
16
|
+
nthThreshold?: number;
|
|
17
|
+
/**
|
|
18
|
+
* how many tries to optimise and shorten the selector
|
|
19
|
+
*
|
|
20
|
+
* default 10_000
|
|
21
|
+
* */
|
|
22
|
+
maxOptimiseTries?: number;
|
|
23
|
+
}
|
|
24
|
+
export default function (app: App, options?: MouseHandlerOptions): void;
|
package/lib/modules/mouse.js
CHANGED
|
@@ -3,13 +3,13 @@ import { normSpaces, hasOpenreplayAttribute, getLabelAttribute } from '../utils.
|
|
|
3
3
|
import { MouseMove, MouseClick } from '../app/messages.gen.js';
|
|
4
4
|
import { getInputLabel } from './input.js';
|
|
5
5
|
import { finder } from '@medv/finder';
|
|
6
|
-
function _getSelector(target, document) {
|
|
6
|
+
function _getSelector(target, document, options) {
|
|
7
7
|
const selector = finder(target, {
|
|
8
8
|
root: document.body,
|
|
9
9
|
seedMinLength: 3,
|
|
10
|
-
optimizedMinLength: 2,
|
|
11
|
-
threshold: 1000,
|
|
12
|
-
maxNumberOfTries: 10000,
|
|
10
|
+
optimizedMinLength: (options === null || options === void 0 ? void 0 : options.minSelectorDepth) || 2,
|
|
11
|
+
threshold: (options === null || options === void 0 ? void 0 : options.nthThreshold) || 1000,
|
|
12
|
+
maxNumberOfTries: (options === null || options === void 0 ? void 0 : options.maxOptimiseTries) || 10000,
|
|
13
13
|
});
|
|
14
14
|
return selector;
|
|
15
15
|
}
|
|
@@ -24,7 +24,7 @@ function isClickable(element) {
|
|
|
24
24
|
element.onclick != null ||
|
|
25
25
|
element.getAttribute('role') === 'button');
|
|
26
26
|
//|| element.className.includes("btn")
|
|
27
|
-
// MBTODO:
|
|
27
|
+
// MBTODO: intercept addEventListener
|
|
28
28
|
}
|
|
29
29
|
//TODO: fix (typescript is not sure about target variable after assignation of svg)
|
|
30
30
|
function getTarget(target, document) {
|
|
@@ -64,7 +64,8 @@ function _getTarget(target, document) {
|
|
|
64
64
|
}
|
|
65
65
|
return target === document.documentElement ? null : target;
|
|
66
66
|
}
|
|
67
|
-
export default function (app) {
|
|
67
|
+
export default function (app, options) {
|
|
68
|
+
const { disableClickmaps = false } = options || {};
|
|
68
69
|
function getTargetLabel(target) {
|
|
69
70
|
const dl = getLabelAttribute(target);
|
|
70
71
|
if (dl !== null) {
|
|
@@ -103,8 +104,8 @@ export default function (app) {
|
|
|
103
104
|
}
|
|
104
105
|
};
|
|
105
106
|
const patchDocument = (document, topframe = false) => {
|
|
106
|
-
function getSelector(id, target) {
|
|
107
|
-
return (selectorMap[id] = selectorMap[id] || _getSelector(target, document));
|
|
107
|
+
function getSelector(id, target, options) {
|
|
108
|
+
return (selectorMap[id] = selectorMap[id] || _getSelector(target, document, options));
|
|
108
109
|
}
|
|
109
110
|
const attachListener = topframe
|
|
110
111
|
? app.attachEventListener.bind(app) // attached/removed on start/stop
|
|
@@ -130,7 +131,7 @@ export default function (app) {
|
|
|
130
131
|
const id = app.nodes.getID(target);
|
|
131
132
|
if (id !== undefined) {
|
|
132
133
|
sendMouseMove();
|
|
133
|
-
app.send(MouseClick(id, mouseTarget === target ? Math.round(performance.now() - mouseTargetTime) : 0, getTargetLabel(target), isClickable(target) ? getSelector(id, target) : ''), true);
|
|
134
|
+
app.send(MouseClick(id, mouseTarget === target ? Math.round(performance.now() - mouseTargetTime) : 0, getTargetLabel(target), isClickable(target) && !disableClickmaps ? getSelector(id, target, options) : ''), true);
|
|
134
135
|
}
|
|
135
136
|
mouseTarget = null;
|
|
136
137
|
});
|