@openreplay/tracker 3.6.3 → 3.6.6
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/.eslintignore +8 -0
- package/cjs/app/guards.js +1 -2
- package/cjs/app/index.d.ts +15 -13
- package/cjs/app/index.js +58 -42
- package/cjs/app/logger.js +6 -3
- package/cjs/app/observer/iframe_observer.d.ts +1 -1
- package/cjs/app/observer/iframe_observer.js +1 -1
- package/cjs/app/observer/observer.d.ts +2 -3
- package/cjs/app/observer/observer.js +38 -40
- package/cjs/app/observer/shadow_root_observer.d.ts +1 -1
- package/cjs/app/observer/shadow_root_observer.js +1 -1
- package/cjs/app/observer/top_observer.d.ts +2 -2
- package/cjs/app/observer/top_observer.js +12 -11
- package/cjs/app/sanitizer.d.ts +1 -1
- package/cjs/app/sanitizer.js +5 -5
- package/cjs/app/session.d.ts +14 -2
- package/cjs/app/session.js +19 -6
- package/cjs/app/ticker.d.ts +1 -1
- package/cjs/common/messages.d.ts +1 -1
- package/cjs/common/messages.js +69 -120
- package/cjs/common/webworker.d.ts +3 -3
- package/cjs/index.d.ts +9 -8
- package/cjs/index.js +34 -28
- package/cjs/modules/connection.d.ts +1 -1
- package/cjs/modules/console.d.ts +1 -1
- package/cjs/modules/console.js +5 -5
- package/cjs/modules/cssrules.d.ts +1 -1
- package/cjs/modules/cssrules.js +3 -3
- package/cjs/modules/exception.d.ts +2 -2
- package/cjs/modules/exception.js +7 -6
- package/cjs/modules/img.d.ts +1 -1
- package/cjs/modules/img.js +15 -12
- package/cjs/modules/input.d.ts +1 -1
- package/cjs/modules/input.js +15 -15
- package/cjs/modules/longtasks.d.ts +1 -1
- package/cjs/modules/longtasks.js +13 -5
- package/cjs/modules/mouse.d.ts +1 -1
- package/cjs/modules/mouse.js +10 -12
- package/cjs/modules/performance.d.ts +1 -1
- package/cjs/modules/scroll.d.ts +1 -1
- package/cjs/modules/timing.d.ts +1 -1
- package/cjs/modules/timing.js +12 -24
- package/cjs/modules/viewport.d.ts +1 -1
- package/cjs/utils.js +7 -7
- package/cjs/vendors/finder/finder.js +53 -48
- package/lib/app/guards.js +1 -2
- package/lib/app/index.d.ts +15 -13
- package/lib/app/index.js +67 -51
- package/lib/app/logger.js +6 -3
- package/lib/app/observer/iframe_observer.d.ts +1 -1
- package/lib/app/observer/iframe_observer.js +3 -3
- package/lib/app/observer/observer.d.ts +2 -3
- package/lib/app/observer/observer.js +40 -42
- package/lib/app/observer/shadow_root_observer.d.ts +1 -1
- package/lib/app/observer/shadow_root_observer.js +3 -3
- package/lib/app/observer/top_observer.d.ts +2 -2
- package/lib/app/observer/top_observer.js +17 -16
- package/lib/app/sanitizer.d.ts +1 -1
- package/lib/app/sanitizer.js +7 -7
- package/lib/app/session.d.ts +14 -2
- package/lib/app/session.js +19 -6
- package/lib/app/ticker.d.ts +1 -1
- package/lib/common/messages.d.ts +1 -1
- package/lib/common/messages.js +69 -120
- package/lib/common/tsconfig.tsbuildinfo +1 -1
- package/lib/common/webworker.d.ts +3 -3
- package/lib/index.d.ts +9 -8
- package/lib/index.js +49 -43
- package/lib/modules/connection.d.ts +1 -1
- package/lib/modules/connection.js +1 -1
- package/lib/modules/console.d.ts +1 -1
- package/lib/modules/console.js +8 -8
- package/lib/modules/cssrules.d.ts +1 -1
- package/lib/modules/cssrules.js +5 -5
- package/lib/modules/exception.d.ts +2 -2
- package/lib/modules/exception.js +8 -7
- package/lib/modules/img.d.ts +1 -1
- package/lib/modules/img.js +18 -15
- package/lib/modules/input.d.ts +1 -1
- package/lib/modules/input.js +18 -18
- package/lib/modules/longtasks.d.ts +1 -1
- package/lib/modules/longtasks.js +14 -6
- package/lib/modules/mouse.d.ts +1 -1
- package/lib/modules/mouse.js +14 -16
- package/lib/modules/performance.d.ts +1 -1
- package/lib/modules/performance.js +2 -2
- package/lib/modules/scroll.d.ts +1 -1
- package/lib/modules/scroll.js +2 -2
- package/lib/modules/timing.d.ts +1 -1
- package/lib/modules/timing.js +15 -27
- package/lib/modules/viewport.d.ts +1 -1
- package/lib/modules/viewport.js +1 -1
- package/lib/utils.js +7 -7
- package/lib/vendors/finder/finder.js +53 -48
- package/package.json +28 -10
package/lib/modules/mouse.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { hasTag, isSVGElement } from
|
|
2
|
-
import { normSpaces, hasOpenreplayAttribute, getLabelAttribute
|
|
3
|
-
import { MouseMove, MouseClick } from
|
|
4
|
-
import { getInputLabel } from
|
|
1
|
+
import { hasTag, isSVGElement } from '../app/guards.js';
|
|
2
|
+
import { normSpaces, hasOpenreplayAttribute, getLabelAttribute } from '../utils.js';
|
|
3
|
+
import { MouseMove, MouseClick } from '../common/messages.js';
|
|
4
|
+
import { getInputLabel } from './input.js';
|
|
5
5
|
function _getSelector(target) {
|
|
6
6
|
let el = target;
|
|
7
7
|
let selector = null;
|
|
@@ -10,9 +10,10 @@ function _getSelector(target) {
|
|
|
10
10
|
return `#${el.id}` + (selector ? ` > ${selector}` : '');
|
|
11
11
|
}
|
|
12
12
|
selector =
|
|
13
|
-
el.className
|
|
14
|
-
.
|
|
15
|
-
.
|
|
13
|
+
el.className
|
|
14
|
+
.split(' ')
|
|
15
|
+
.map((cn) => cn.trim())
|
|
16
|
+
.filter((cn) => cn !== '')
|
|
16
17
|
.reduce((sel, cn) => `${sel}.${cn}`, el.tagName.toLowerCase()) +
|
|
17
18
|
(selector ? ` > ${selector}` : '');
|
|
18
19
|
if (el === document.body) {
|
|
@@ -24,12 +25,12 @@ function _getSelector(target) {
|
|
|
24
25
|
}
|
|
25
26
|
function isClickable(element) {
|
|
26
27
|
const tag = element.tagName.toUpperCase();
|
|
27
|
-
return tag === 'BUTTON' ||
|
|
28
|
+
return (tag === 'BUTTON' ||
|
|
28
29
|
tag === 'A' ||
|
|
29
30
|
tag === 'LI' ||
|
|
30
31
|
tag === 'SELECT' ||
|
|
31
32
|
element.onclick != null ||
|
|
32
|
-
element.getAttribute('role') === 'button';
|
|
33
|
+
element.getAttribute('role') === 'button');
|
|
33
34
|
//|| element.className.includes("btn")
|
|
34
35
|
// MBTODO: intersect addEventListener
|
|
35
36
|
}
|
|
@@ -64,8 +65,7 @@ function _getTarget(target) {
|
|
|
64
65
|
if (tag === 'INPUT') {
|
|
65
66
|
return element;
|
|
66
67
|
}
|
|
67
|
-
if (isClickable(element) ||
|
|
68
|
-
getLabelAttribute(element) !== null) {
|
|
68
|
+
if (isClickable(element) || getLabelAttribute(element) !== null) {
|
|
69
69
|
return element;
|
|
70
70
|
}
|
|
71
71
|
element = element.parentElement;
|
|
@@ -78,7 +78,7 @@ export default function (app) {
|
|
|
78
78
|
if (dl !== null) {
|
|
79
79
|
return dl;
|
|
80
80
|
}
|
|
81
|
-
if (hasTag(target,
|
|
81
|
+
if (hasTag(target, 'INPUT')) {
|
|
82
82
|
return getInputLabel(target);
|
|
83
83
|
}
|
|
84
84
|
if (isClickable(target)) {
|
|
@@ -110,7 +110,7 @@ export default function (app) {
|
|
|
110
110
|
};
|
|
111
111
|
const selectorMap = {};
|
|
112
112
|
function getSelector(id, target) {
|
|
113
|
-
return selectorMap[id] = selectorMap[id] || _getSelector(target);
|
|
113
|
+
return (selectorMap[id] = selectorMap[id] || _getSelector(target));
|
|
114
114
|
}
|
|
115
115
|
app.attachEventListener(document.documentElement, 'mouseover', (e) => {
|
|
116
116
|
const target = getTarget(e.target);
|
|
@@ -132,9 +132,7 @@ export default function (app) {
|
|
|
132
132
|
const id = app.nodes.getID(target);
|
|
133
133
|
if (id !== undefined) {
|
|
134
134
|
sendMouseMove();
|
|
135
|
-
app.send(new MouseClick(id, mouseTarget === target
|
|
136
|
-
? Math.round(performance.now() - mouseTargetTime)
|
|
137
|
-
: 0, getTargetLabel(target), getSelector(id, target)), true);
|
|
135
|
+
app.send(new MouseClick(id, mouseTarget === target ? Math.round(performance.now() - mouseTargetTime) : 0, getTargetLabel(target), getSelector(id, target)), true);
|
|
138
136
|
}
|
|
139
137
|
mouseTarget = null;
|
|
140
138
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IN_BROWSER } from
|
|
2
|
-
import { PerformanceTrack } from
|
|
1
|
+
import { IN_BROWSER } from '../utils.js';
|
|
2
|
+
import { PerformanceTrack } from '../common/messages.js';
|
|
3
3
|
const perf = IN_BROWSER && 'performance' in window && 'memory' in performance // works in Chrome only
|
|
4
4
|
? performance
|
|
5
5
|
: { memory: {} };
|
package/lib/modules/scroll.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type App from
|
|
1
|
+
import type App from '../app/index.js';
|
|
2
2
|
export default function (app: App): void;
|
package/lib/modules/scroll.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SetViewportScroll, SetNodeScroll } from
|
|
2
|
-
import { isElementNode } from
|
|
1
|
+
import { SetViewportScroll, SetNodeScroll } from '../common/messages.js';
|
|
2
|
+
import { isElementNode } from '../app/guards.js';
|
|
3
3
|
export default function (app) {
|
|
4
4
|
let documentScroll = false;
|
|
5
5
|
const nodeScroll = new Map();
|
package/lib/modules/timing.d.ts
CHANGED
package/lib/modules/timing.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { hasTag } from
|
|
2
|
-
import { isURL } from
|
|
3
|
-
import { ResourceTiming, PageLoadTiming, PageRenderTiming } from
|
|
1
|
+
import { hasTag } from '../app/guards.js';
|
|
2
|
+
import { isURL } from '../utils.js';
|
|
3
|
+
import { ResourceTiming, PageLoadTiming, PageRenderTiming } from '../common/messages.js';
|
|
4
4
|
function getPaintBlocks(resources) {
|
|
5
5
|
const paintBlocks = [];
|
|
6
6
|
const elements = document.getElementsByTagName('*');
|
|
@@ -8,7 +8,7 @@ function getPaintBlocks(resources) {
|
|
|
8
8
|
for (let i = 0; i < elements.length; i++) {
|
|
9
9
|
const element = elements[i];
|
|
10
10
|
let src = '';
|
|
11
|
-
if (hasTag(element,
|
|
11
|
+
if (hasTag(element, 'IMG')) {
|
|
12
12
|
src = element.currentSrc || element.src;
|
|
13
13
|
}
|
|
14
14
|
if (!src) {
|
|
@@ -34,9 +34,7 @@ function getPaintBlocks(resources) {
|
|
|
34
34
|
const bottom = Math.min(rect.bottom, window.innerHeight ||
|
|
35
35
|
(document.documentElement && document.documentElement.clientHeight) ||
|
|
36
36
|
0);
|
|
37
|
-
const right = Math.min(rect.right, window.innerWidth ||
|
|
38
|
-
(document.documentElement && document.documentElement.clientWidth) ||
|
|
39
|
-
0);
|
|
37
|
+
const right = Math.min(rect.right, window.innerWidth || (document.documentElement && document.documentElement.clientWidth) || 0);
|
|
40
38
|
if (bottom <= top || right <= left)
|
|
41
39
|
continue;
|
|
42
40
|
const area = (bottom - top) * (right - left);
|
|
@@ -46,8 +44,7 @@ function getPaintBlocks(resources) {
|
|
|
46
44
|
}
|
|
47
45
|
function calculateSpeedIndex(firstContentfulPaint, paintBlocks) {
|
|
48
46
|
let a = (Math.max((document.documentElement && document.documentElement.clientWidth) || 0, window.innerWidth || 0) *
|
|
49
|
-
Math.max((document.documentElement && document.documentElement.clientHeight) ||
|
|
50
|
-
0, window.innerHeight || 0)) /
|
|
47
|
+
Math.max((document.documentElement && document.documentElement.clientHeight) || 0, window.innerHeight || 0)) /
|
|
51
48
|
10;
|
|
52
49
|
let s = a * firstContentfulPaint;
|
|
53
50
|
for (let i = 0; i < paintBlocks.length; i++) {
|
|
@@ -76,16 +73,13 @@ export default function (app, opts) {
|
|
|
76
73
|
if (resources !== null) {
|
|
77
74
|
resources[entry.name] = entry.startTime + entry.duration;
|
|
78
75
|
}
|
|
79
|
-
app.send(new ResourceTiming(entry.startTime + performance.timing.navigationStart, entry.duration, entry.responseStart && entry.startTime
|
|
80
|
-
? entry.responseStart - entry.startTime
|
|
81
|
-
: 0, entry.transferSize > entry.encodedBodySize
|
|
82
|
-
? entry.transferSize - entry.encodedBodySize
|
|
83
|
-
: 0, entry.encodedBodySize || 0, entry.decodedBodySize || 0, entry.name, entry.initiatorType));
|
|
76
|
+
app.send(new ResourceTiming(entry.startTime + performance.timing.navigationStart, entry.duration, entry.responseStart && entry.startTime ? entry.responseStart - entry.startTime : 0, entry.transferSize > entry.encodedBodySize ? entry.transferSize - entry.encodedBodySize : 0, entry.encodedBodySize || 0, entry.decodedBodySize || 0, entry.name, entry.initiatorType));
|
|
84
77
|
}
|
|
85
78
|
const observer = new PerformanceObserver((list) => list.getEntries().forEach(resourceTiming));
|
|
86
79
|
let prevSessionID;
|
|
87
80
|
app.attachStartCallback(function ({ sessionID }) {
|
|
88
|
-
if (sessionID !== prevSessionID) {
|
|
81
|
+
if (sessionID !== prevSessionID) {
|
|
82
|
+
// Send past page resources on a newly started session
|
|
89
83
|
performance.getEntriesByType('resource').forEach(resourceTiming);
|
|
90
84
|
prevSessionID = sessionID;
|
|
91
85
|
}
|
|
@@ -102,9 +96,7 @@ export default function (app, opts) {
|
|
|
102
96
|
return;
|
|
103
97
|
}
|
|
104
98
|
if (firstPaint === 0 || firstContentfulPaint === 0) {
|
|
105
|
-
performance
|
|
106
|
-
.getEntriesByType('paint')
|
|
107
|
-
.forEach((entry) => {
|
|
99
|
+
performance.getEntriesByType('paint').forEach((entry) => {
|
|
108
100
|
const { name, startTime } = entry;
|
|
109
101
|
switch (name) {
|
|
110
102
|
case 'first-paint':
|
|
@@ -142,23 +134,19 @@ export default function (app, opts) {
|
|
|
142
134
|
if (time - interactiveWindowTickTime > 50) {
|
|
143
135
|
interactiveWindowStartTime = time;
|
|
144
136
|
}
|
|
145
|
-
interactiveWindowTickTime =
|
|
146
|
-
time - interactiveWindowStartTime > 5000 ? null : time;
|
|
137
|
+
interactiveWindowTickTime = time - interactiveWindowStartTime > 5000 ? null : time;
|
|
147
138
|
}
|
|
148
|
-
if ((paintBlocks !== null && interactiveWindowTickTime === null) ||
|
|
149
|
-
time > 30000) {
|
|
139
|
+
if ((paintBlocks !== null && interactiveWindowTickTime === null) || time > 30000) {
|
|
150
140
|
pageRenderTimingSent = true;
|
|
151
141
|
resources = null;
|
|
152
142
|
const speedIndex = paintBlocks === null
|
|
153
143
|
? 0
|
|
154
144
|
: calculateSpeedIndex(firstContentfulPaint || firstPaint, paintBlocks);
|
|
155
145
|
const timeToInteractive = interactiveWindowTickTime === null
|
|
156
|
-
? Math.max(interactiveWindowStartTime, firstContentfulPaint, performance.timing.domContentLoadedEventEnd -
|
|
157
|
-
|
|
146
|
+
? Math.max(interactiveWindowStartTime, firstContentfulPaint, performance.timing.domContentLoadedEventEnd - performance.timing.navigationStart ||
|
|
147
|
+
0)
|
|
158
148
|
: 0;
|
|
159
|
-
app.send(new PageRenderTiming(speedIndex, firstContentfulPaint > visuallyComplete
|
|
160
|
-
? firstContentfulPaint
|
|
161
|
-
: visuallyComplete, timeToInteractive));
|
|
149
|
+
app.send(new PageRenderTiming(speedIndex, firstContentfulPaint > visuallyComplete ? firstContentfulPaint : visuallyComplete, timeToInteractive));
|
|
162
150
|
}
|
|
163
151
|
});
|
|
164
152
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type App from
|
|
1
|
+
import type App from '../app/index.js';
|
|
2
2
|
export default function (app: App): void;
|
package/lib/modules/viewport.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SetPageLocation, SetViewportSize, SetPageVisibility
|
|
1
|
+
import { SetPageLocation, SetViewportSize, SetPageVisibility } from '../common/messages.js';
|
|
2
2
|
export default function (app) {
|
|
3
3
|
let url, width, height;
|
|
4
4
|
let navigationStart = performance.timing.navigationStart;
|
package/lib/utils.js
CHANGED
|
@@ -11,25 +11,25 @@ export function normSpaces(str) {
|
|
|
11
11
|
export function isURL(s) {
|
|
12
12
|
return s.startsWith('https://') || s.startsWith('http://');
|
|
13
13
|
}
|
|
14
|
-
export const IN_BROWSER = !(typeof window ===
|
|
14
|
+
export const IN_BROWSER = !(typeof window === 'undefined');
|
|
15
15
|
// TODO: JOIN IT WITH LOGGER somehow (use logging decorators?); Don't forget about index.js loggin when there is no logger instance.
|
|
16
16
|
export const DOCS_HOST = 'https://docs.openreplay.com';
|
|
17
17
|
const warnedFeatures = {};
|
|
18
|
-
export function deprecationWarn(nameOfFeature, useInstead, docsPath =
|
|
18
|
+
export function deprecationWarn(nameOfFeature, useInstead, docsPath = '/') {
|
|
19
19
|
if (warnedFeatures[nameOfFeature]) {
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
|
-
console.warn(`OpenReplay: ${nameOfFeature} is deprecated. ${useInstead ? `Please, use ${useInstead} instead.` :
|
|
22
|
+
console.warn(`OpenReplay: ${nameOfFeature} is deprecated. ${useInstead ? `Please, use ${useInstead} instead.` : ''} Visit ${DOCS_HOST}${docsPath} for more information.`);
|
|
23
23
|
warnedFeatures[nameOfFeature] = true;
|
|
24
24
|
}
|
|
25
25
|
export function getLabelAttribute(e) {
|
|
26
|
-
let value = e.getAttribute(
|
|
26
|
+
let value = e.getAttribute('data-openreplay-label');
|
|
27
27
|
if (value !== null) {
|
|
28
28
|
return value;
|
|
29
29
|
}
|
|
30
|
-
value = e.getAttribute(
|
|
30
|
+
value = e.getAttribute('data-asayer-label');
|
|
31
31
|
if (value !== null) {
|
|
32
|
-
deprecationWarn(
|
|
32
|
+
deprecationWarn('"data-asayer-label" attribute', '"data-openreplay-label" attribute', '/');
|
|
33
33
|
}
|
|
34
34
|
return value;
|
|
35
35
|
}
|
|
@@ -40,7 +40,7 @@ export function hasOpenreplayAttribute(e, name) {
|
|
|
40
40
|
}
|
|
41
41
|
const oldName = `data-asayer-${name}`;
|
|
42
42
|
if (e.hasAttribute(oldName)) {
|
|
43
|
-
deprecationWarn(`"${oldName}" attribute`, `"${newName}" attribute`,
|
|
43
|
+
deprecationWarn(`"${oldName}" attribute`, `"${newName}" attribute`, '/installation/sanitize-data');
|
|
44
44
|
return true;
|
|
45
45
|
}
|
|
46
46
|
return false;
|
|
@@ -8,10 +8,10 @@ let config;
|
|
|
8
8
|
let rootDocument;
|
|
9
9
|
export function finder(input, options) {
|
|
10
10
|
if (input.nodeType !== Node.ELEMENT_NODE) {
|
|
11
|
-
throw new Error(
|
|
11
|
+
throw new Error("Can't generate CSS selector for non-element node type.");
|
|
12
12
|
}
|
|
13
|
-
if (
|
|
14
|
-
return
|
|
13
|
+
if ('html' === input.tagName.toLowerCase()) {
|
|
14
|
+
return 'html';
|
|
15
15
|
}
|
|
16
16
|
const defaults = {
|
|
17
17
|
root: document.body,
|
|
@@ -35,7 +35,7 @@ export function finder(input, options) {
|
|
|
35
35
|
return selector(path);
|
|
36
36
|
}
|
|
37
37
|
else {
|
|
38
|
-
throw new Error(
|
|
38
|
+
throw new Error('Selector was not found.');
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
function findRootDocument(rootNode, defaults) {
|
|
@@ -49,30 +49,33 @@ function findRootDocument(rootNode, defaults) {
|
|
|
49
49
|
}
|
|
50
50
|
function bottomUpSearch(input, limit, fallback) {
|
|
51
51
|
let path = null;
|
|
52
|
-
|
|
52
|
+
const stack = [];
|
|
53
53
|
let current = input;
|
|
54
54
|
let i = 0;
|
|
55
55
|
while (current && current !== config.root.parentElement) {
|
|
56
|
-
let level = maybe(id(current)) ||
|
|
56
|
+
let level = maybe(id(current)) ||
|
|
57
|
+
maybe(...attr(current)) ||
|
|
58
|
+
maybe(...classNames(current)) ||
|
|
59
|
+
maybe(tagName(current)) || [any()];
|
|
57
60
|
const nth = index(current);
|
|
58
61
|
if (limit === Limit.All) {
|
|
59
62
|
if (nth) {
|
|
60
|
-
level = level.concat(level.filter(dispensableNth).map(node => nthChild(node, nth)));
|
|
63
|
+
level = level.concat(level.filter(dispensableNth).map((node) => nthChild(node, nth)));
|
|
61
64
|
}
|
|
62
65
|
}
|
|
63
66
|
else if (limit === Limit.Two) {
|
|
64
67
|
level = level.slice(0, 1);
|
|
65
68
|
if (nth) {
|
|
66
|
-
level = level.concat(level.filter(dispensableNth).map(node => nthChild(node, nth)));
|
|
69
|
+
level = level.concat(level.filter(dispensableNth).map((node) => nthChild(node, nth)));
|
|
67
70
|
}
|
|
68
71
|
}
|
|
69
72
|
else if (limit === Limit.One) {
|
|
70
|
-
const [node] = level = level.slice(0, 1);
|
|
73
|
+
const [node] = (level = level.slice(0, 1));
|
|
71
74
|
if (nth && dispensableNth(node)) {
|
|
72
75
|
level = [nthChild(node, nth)];
|
|
73
76
|
}
|
|
74
77
|
}
|
|
75
|
-
for (
|
|
78
|
+
for (const node of level) {
|
|
76
79
|
node.level = i;
|
|
77
80
|
}
|
|
78
81
|
stack.push(level);
|
|
@@ -95,7 +98,7 @@ function findUniquePath(stack, fallback) {
|
|
|
95
98
|
if (paths.length > config.threshold) {
|
|
96
99
|
return fallback ? fallback() : null;
|
|
97
100
|
}
|
|
98
|
-
for (
|
|
101
|
+
for (const candidate of paths) {
|
|
99
102
|
if (unique(candidate)) {
|
|
100
103
|
return candidate;
|
|
101
104
|
}
|
|
@@ -118,7 +121,7 @@ function selector(path) {
|
|
|
118
121
|
return query;
|
|
119
122
|
}
|
|
120
123
|
function penalty(path) {
|
|
121
|
-
return path.map(node => node.penalty).reduce((acc, i) => acc + i, 0);
|
|
124
|
+
return path.map((node) => node.penalty).reduce((acc, i) => acc + i, 0);
|
|
122
125
|
}
|
|
123
126
|
function unique(path) {
|
|
124
127
|
switch (rootDocument.querySelectorAll(selector(path)).length) {
|
|
@@ -131,10 +134,10 @@ function unique(path) {
|
|
|
131
134
|
}
|
|
132
135
|
}
|
|
133
136
|
function id(input) {
|
|
134
|
-
const elementId = input.getAttribute(
|
|
137
|
+
const elementId = input.getAttribute('id');
|
|
135
138
|
if (elementId && config.idName(elementId)) {
|
|
136
139
|
return {
|
|
137
|
-
name:
|
|
140
|
+
name: '#' + cssesc(elementId, { isIdentifier: true }),
|
|
138
141
|
penalty: 0,
|
|
139
142
|
};
|
|
140
143
|
}
|
|
@@ -143,16 +146,15 @@ function id(input) {
|
|
|
143
146
|
function attr(input) {
|
|
144
147
|
const attrs = Array.from(input.attributes).filter((attr) => config.attr(attr.name, attr.value));
|
|
145
148
|
return attrs.map((attr) => ({
|
|
146
|
-
name:
|
|
147
|
-
penalty: 0.5
|
|
149
|
+
name: '[' + cssesc(attr.name, { isIdentifier: true }) + '="' + cssesc(attr.value) + '"]',
|
|
150
|
+
penalty: 0.5,
|
|
148
151
|
}));
|
|
149
152
|
}
|
|
150
153
|
function classNames(input) {
|
|
151
|
-
const names = Array.from(input.classList)
|
|
152
|
-
.filter(config.className);
|
|
154
|
+
const names = Array.from(input.classList).filter(config.className);
|
|
153
155
|
return names.map((name) => ({
|
|
154
|
-
name:
|
|
155
|
-
penalty: 1
|
|
156
|
+
name: '.' + cssesc(name, { isIdentifier: true }),
|
|
157
|
+
penalty: 1,
|
|
156
158
|
}));
|
|
157
159
|
}
|
|
158
160
|
function tagName(input) {
|
|
@@ -160,15 +162,15 @@ function tagName(input) {
|
|
|
160
162
|
if (config.tagName(name)) {
|
|
161
163
|
return {
|
|
162
164
|
name,
|
|
163
|
-
penalty: 2
|
|
165
|
+
penalty: 2,
|
|
164
166
|
};
|
|
165
167
|
}
|
|
166
168
|
return null;
|
|
167
169
|
}
|
|
168
170
|
function any() {
|
|
169
171
|
return {
|
|
170
|
-
name:
|
|
171
|
-
penalty: 3
|
|
172
|
+
name: '*',
|
|
173
|
+
penalty: 3,
|
|
172
174
|
};
|
|
173
175
|
}
|
|
174
176
|
function index(input) {
|
|
@@ -195,11 +197,11 @@ function index(input) {
|
|
|
195
197
|
function nthChild(node, i) {
|
|
196
198
|
return {
|
|
197
199
|
name: node.name + `:nth-child(${i})`,
|
|
198
|
-
penalty: node.penalty + 1
|
|
200
|
+
penalty: node.penalty + 1,
|
|
199
201
|
};
|
|
200
202
|
}
|
|
201
203
|
function dispensableNth(node) {
|
|
202
|
-
return node.name !==
|
|
204
|
+
return node.name !== 'html' && !node.name.startsWith('#');
|
|
203
205
|
}
|
|
204
206
|
function maybe(...level) {
|
|
205
207
|
const list = level.filter(notEmpty);
|
|
@@ -214,7 +216,7 @@ function notEmpty(value) {
|
|
|
214
216
|
function combinations(stack, path = []) {
|
|
215
217
|
const paths = [];
|
|
216
218
|
if (stack.length > 0) {
|
|
217
|
-
for (
|
|
219
|
+
for (const node of stack[0]) {
|
|
218
220
|
paths.push(...combinations(stack.slice(1, stack.length), path.concat(node)));
|
|
219
221
|
}
|
|
220
222
|
}
|
|
@@ -228,7 +230,7 @@ function sort(paths) {
|
|
|
228
230
|
}
|
|
229
231
|
function optimize(path, input, scope = {
|
|
230
232
|
counter: 0,
|
|
231
|
-
visited: new Map()
|
|
233
|
+
visited: new Map(),
|
|
232
234
|
}) {
|
|
233
235
|
const paths = [];
|
|
234
236
|
if (path.length > 2 && path.length > config.optimizedMinLength) {
|
|
@@ -259,20 +261,20 @@ const regexAnySingleEscape = /[ -,\.\/:-@\[-\^`\{-~]/;
|
|
|
259
261
|
const regexSingleEscape = /[ -,\.\/:-@\[\]\^`\{-~]/;
|
|
260
262
|
const regexExcessiveSpaces = /(^|\\+)?(\\[A-F0-9]{1,6})\x20(?![a-fA-F0-9\x20])/g;
|
|
261
263
|
const defaultOptions = {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
264
|
+
escapeEverything: false,
|
|
265
|
+
isIdentifier: false,
|
|
266
|
+
quotes: 'single',
|
|
267
|
+
wrap: false,
|
|
266
268
|
};
|
|
267
269
|
function cssesc(string, opt = {}) {
|
|
268
270
|
const options = Object.assign(Object.assign({}, defaultOptions), opt);
|
|
269
|
-
if (options.quotes !=
|
|
270
|
-
options.quotes =
|
|
271
|
+
if (options.quotes != 'single' && options.quotes != 'double') {
|
|
272
|
+
options.quotes = 'single';
|
|
271
273
|
}
|
|
272
|
-
const quote = options.quotes ==
|
|
274
|
+
const quote = options.quotes == 'double' ? '"' : "'";
|
|
273
275
|
const isIdentifier = options.isIdentifier;
|
|
274
276
|
const firstChar = string.charAt(0);
|
|
275
|
-
let output =
|
|
277
|
+
let output = '';
|
|
276
278
|
let counter = 0;
|
|
277
279
|
const length = string.length;
|
|
278
280
|
while (counter < length) {
|
|
@@ -280,13 +282,13 @@ function cssesc(string, opt = {}) {
|
|
|
280
282
|
let codePoint = character.charCodeAt(0);
|
|
281
283
|
let value = void 0;
|
|
282
284
|
// If it’s not a printable ASCII character…
|
|
283
|
-
if (codePoint < 0x20 || codePoint >
|
|
284
|
-
if (codePoint >=
|
|
285
|
+
if (codePoint < 0x20 || codePoint > 0x7e) {
|
|
286
|
+
if (codePoint >= 0xd800 && codePoint <= 0xdbff && counter < length) {
|
|
285
287
|
// It’s a high surrogate, and there is a next character.
|
|
286
288
|
const extra = string.charCodeAt(counter++);
|
|
287
|
-
if ((extra &
|
|
289
|
+
if ((extra & 0xfc00) == 0xdc00) {
|
|
288
290
|
// next character is low surrogate
|
|
289
|
-
codePoint = ((codePoint &
|
|
291
|
+
codePoint = ((codePoint & 0x3ff) << 10) + (extra & 0x3ff) + 0x10000;
|
|
290
292
|
}
|
|
291
293
|
else {
|
|
292
294
|
// It’s an unmatched surrogate; only append this code unit, in case
|
|
@@ -294,22 +296,25 @@ function cssesc(string, opt = {}) {
|
|
|
294
296
|
counter--;
|
|
295
297
|
}
|
|
296
298
|
}
|
|
297
|
-
value =
|
|
299
|
+
value = '\\' + codePoint.toString(16).toUpperCase() + ' ';
|
|
298
300
|
}
|
|
299
301
|
else {
|
|
300
302
|
if (options.escapeEverything) {
|
|
301
303
|
if (regexAnySingleEscape.test(character)) {
|
|
302
|
-
value =
|
|
304
|
+
value = '\\' + character;
|
|
303
305
|
}
|
|
304
306
|
else {
|
|
305
|
-
value =
|
|
307
|
+
value = '\\' + codePoint.toString(16).toUpperCase() + ' ';
|
|
306
308
|
}
|
|
307
309
|
}
|
|
308
310
|
else if (/[\t\n\f\r\x0B]/.test(character)) {
|
|
309
|
-
value =
|
|
311
|
+
value = '\\' + codePoint.toString(16).toUpperCase() + ' ';
|
|
310
312
|
}
|
|
311
|
-
else if (character ==
|
|
312
|
-
|
|
313
|
+
else if (character == '\\' ||
|
|
314
|
+
(!isIdentifier &&
|
|
315
|
+
((character == '"' && quote == character) || (character == "'" && quote == character))) ||
|
|
316
|
+
(isIdentifier && regexSingleEscape.test(character))) {
|
|
317
|
+
value = '\\' + character;
|
|
313
318
|
}
|
|
314
319
|
else {
|
|
315
320
|
value = character;
|
|
@@ -319,10 +324,10 @@ function cssesc(string, opt = {}) {
|
|
|
319
324
|
}
|
|
320
325
|
if (isIdentifier) {
|
|
321
326
|
if (/^-[-\d]/.test(output)) {
|
|
322
|
-
output =
|
|
327
|
+
output = '\\-' + output.slice(1);
|
|
323
328
|
}
|
|
324
329
|
else if (/\d/.test(firstChar)) {
|
|
325
|
-
output =
|
|
330
|
+
output = '\\3' + firstChar + ' ' + output.slice(1);
|
|
326
331
|
}
|
|
327
332
|
}
|
|
328
333
|
// Remove spaces after `\HEX` escapes that are not followed by a hex digit,
|
|
@@ -334,7 +339,7 @@ function cssesc(string, opt = {}) {
|
|
|
334
339
|
return $0;
|
|
335
340
|
}
|
|
336
341
|
// Strip the space.
|
|
337
|
-
return ($1 ||
|
|
342
|
+
return ($1 || '') + $2;
|
|
338
343
|
});
|
|
339
344
|
if (!isIdentifier && options.wrap) {
|
|
340
345
|
return quote + output + quote;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openreplay/tracker",
|
|
3
3
|
"description": "The OpenReplay tracker main package",
|
|
4
|
-
"version": "3.6.
|
|
4
|
+
"version": "3.6.6",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"logging",
|
|
7
7
|
"replay"
|
|
@@ -14,33 +14,51 @@
|
|
|
14
14
|
"type": "module",
|
|
15
15
|
"main": "./lib/index.js",
|
|
16
16
|
"scripts": {
|
|
17
|
-
"lint": "eslint src --ext .ts,.js --fix
|
|
17
|
+
"lint": "eslint src --ext .ts,.js --fix",
|
|
18
18
|
"clean": "rm -Rf build && rm -Rf lib && rm -Rf cjs",
|
|
19
|
-
"
|
|
19
|
+
"tscRun": "tsc -b src/main && tsc -b src/webworker && tsc --project src/main/tsconfig-cjs.json",
|
|
20
20
|
"rollup": "rollup --config rollup.config.js",
|
|
21
21
|
"compile": "node --experimental-modules --experimental-json-modules scripts/compile.cjs",
|
|
22
|
-
"build": "npm run clean && npm run
|
|
23
|
-
"prepare": "
|
|
22
|
+
"build": "npm run clean && npm run tscRun && npm run rollup && npm run compile",
|
|
23
|
+
"prepare": "cd ../../ && husky install tracker/.husky/",
|
|
24
|
+
"lint-front": "lint-staged",
|
|
25
|
+
"pret": "prettier src --write"
|
|
24
26
|
},
|
|
25
27
|
"devDependencies": {
|
|
26
28
|
"@babel/core": "^7.10.2",
|
|
27
29
|
"@rollup/plugin-babel": "^5.0.3",
|
|
28
30
|
"@rollup/plugin-node-resolve": "^10.0.0",
|
|
29
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
30
|
-
"@typescript-eslint/parser": "^
|
|
31
|
+
"@typescript-eslint/eslint-plugin": "^5.30.0",
|
|
32
|
+
"@typescript-eslint/parser": "^5.30.0",
|
|
31
33
|
"eslint": "^7.8.0",
|
|
32
|
-
"eslint-
|
|
33
|
-
"prettier": "^2.
|
|
34
|
+
"eslint-config-prettier": "^8.5.0",
|
|
35
|
+
"eslint-plugin-prettier": "^4.2.1",
|
|
36
|
+
"husky": "^8.0.1",
|
|
37
|
+
"lint-staged": "^13.0.3",
|
|
38
|
+
"prettier": "^2.7.1",
|
|
34
39
|
"replace-in-files": "^2.0.3",
|
|
35
40
|
"rollup": "^2.17.0",
|
|
36
41
|
"rollup-plugin-terser": "^6.1.0",
|
|
37
42
|
"semver": "^6.3.0",
|
|
38
|
-
"typescript": "
|
|
43
|
+
"typescript": "4.6.0-dev.20211126"
|
|
39
44
|
},
|
|
40
45
|
"dependencies": {
|
|
41
46
|
"error-stack-parser": "^2.0.6"
|
|
42
47
|
},
|
|
43
48
|
"engines": {
|
|
44
49
|
"node": ">=14.0"
|
|
50
|
+
},
|
|
51
|
+
"husky": {
|
|
52
|
+
"hooks": {
|
|
53
|
+
"pre-commit": "sh lint.sh"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"lint-staged": {
|
|
57
|
+
"*.{js,mjs,jsx,ts,tsx}": [
|
|
58
|
+
"eslint --fix --quiet"
|
|
59
|
+
],
|
|
60
|
+
"*.{json,md,html,js,jsx,ts,tsx}": [
|
|
61
|
+
"prettier --write"
|
|
62
|
+
]
|
|
45
63
|
}
|
|
46
64
|
}
|