@openreplay/tracker 4.0.1 → 4.0.2
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/guards.d.ts +1 -0
- package/cjs/app/guards.js +6 -1
- package/cjs/app/index.d.ts +1 -1
- package/cjs/app/index.js +16 -10
- package/cjs/app/messages.gen.js +1 -0
- package/cjs/app/nodes.d.ts +1 -1
- package/cjs/app/nodes.js +3 -5
- package/cjs/app/observer/iframe_observer.js +1 -0
- package/cjs/app/observer/iframe_offsets.d.ts +8 -0
- package/cjs/app/observer/iframe_offsets.js +59 -0
- package/cjs/app/observer/observer.js +4 -4
- package/cjs/app/observer/top_observer.d.ts +2 -4
- package/cjs/app/observer/top_observer.js +11 -21
- package/cjs/app/sanitizer.d.ts +10 -4
- package/cjs/app/sanitizer.js +33 -15
- package/cjs/app/session.js +1 -1
- package/cjs/common/messages.gen.js +1 -0
- package/cjs/index.d.ts +1 -0
- package/cjs/index.js +7 -7
- package/cjs/modules/constructedStyleSheets.d.ts +4 -0
- package/cjs/modules/{adoptedStyleSheets.js → constructedStyleSheets.js} +21 -20
- package/cjs/modules/cssrules.js +65 -18
- package/cjs/modules/img.js +27 -19
- package/cjs/modules/input.js +2 -2
- package/cjs/modules/mouse.js +11 -7
- package/cjs/modules/scroll.js +32 -12
- package/cjs/utils.d.ts +5 -3
- package/cjs/utils.js +18 -13
- package/lib/app/guards.d.ts +1 -0
- package/lib/app/guards.js +4 -0
- package/lib/app/index.d.ts +1 -1
- package/lib/app/index.js +16 -10
- package/lib/app/messages.gen.js +1 -0
- package/lib/app/nodes.d.ts +1 -1
- package/lib/app/nodes.js +3 -5
- package/lib/app/observer/iframe_observer.js +1 -0
- package/lib/app/observer/iframe_offsets.d.ts +8 -0
- package/lib/app/observer/iframe_offsets.js +56 -0
- package/lib/app/observer/observer.js +4 -4
- package/lib/app/observer/top_observer.d.ts +2 -4
- package/lib/app/observer/top_observer.js +11 -21
- package/lib/app/sanitizer.d.ts +10 -4
- package/lib/app/sanitizer.js +32 -15
- package/lib/app/session.js +1 -1
- package/lib/common/messages.gen.js +1 -0
- package/lib/common/tsconfig.tsbuildinfo +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +5 -6
- package/lib/modules/constructedStyleSheets.d.ts +4 -0
- package/lib/modules/{adoptedStyleSheets.js → constructedStyleSheets.js} +20 -21
- package/lib/modules/cssrules.js +67 -19
- package/lib/modules/img.js +28 -20
- package/lib/modules/input.js +3 -3
- package/lib/modules/mouse.js +11 -7
- package/lib/modules/scroll.js +33 -13
- package/lib/utils.d.ts +5 -3
- package/lib/utils.js +17 -11
- package/package.json +1 -1
- package/cjs/modules/adoptedStyleSheets.d.ts +0 -2
- package/lib/modules/adoptedStyleSheets.d.ts +0 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.styleSheetIDMap = exports.nextID = void 0;
|
|
3
4
|
const messages_gen_js_1 = require("../app/messages.gen.js");
|
|
4
5
|
const guards_js_1 = require("../app/guards.js");
|
|
5
6
|
function hasAdoptedSS(node) {
|
|
@@ -7,6 +8,13 @@ function hasAdoptedSS(node) {
|
|
|
7
8
|
// @ts-ignore
|
|
8
9
|
!!node.adoptedStyleSheets);
|
|
9
10
|
}
|
|
11
|
+
// TODO: incapsulate to be init-ed on-start and join with cssrules.ts under one folder
|
|
12
|
+
let _id = 0xf;
|
|
13
|
+
function nextID() {
|
|
14
|
+
return _id++;
|
|
15
|
+
}
|
|
16
|
+
exports.nextID = nextID;
|
|
17
|
+
exports.styleSheetIDMap = new Map();
|
|
10
18
|
function default_1(app) {
|
|
11
19
|
if (app === null) {
|
|
12
20
|
return;
|
|
@@ -18,10 +26,9 @@ function default_1(app) {
|
|
|
18
26
|
});
|
|
19
27
|
return;
|
|
20
28
|
}
|
|
21
|
-
let nextID = 0xf;
|
|
22
29
|
const styleSheetIDMap = new Map();
|
|
23
30
|
const adoptedStyleSheetsOwnings = new Map();
|
|
24
|
-
const
|
|
31
|
+
const sendAdoptedStyleSheetsUpdate = (root) => {
|
|
25
32
|
let nodeID = app.nodes.getID(root);
|
|
26
33
|
if (root === document) {
|
|
27
34
|
nodeID = 0; // main document doesn't have nodeID. ID count starts from the documentElement
|
|
@@ -39,7 +46,7 @@ function default_1(app) {
|
|
|
39
46
|
let sheetID = styleSheetIDMap.get(s);
|
|
40
47
|
const init = !sheetID;
|
|
41
48
|
if (!sheetID) {
|
|
42
|
-
sheetID =
|
|
49
|
+
sheetID = nextID();
|
|
43
50
|
}
|
|
44
51
|
nowOwning.push(sheetID);
|
|
45
52
|
if (!pastOwning.includes(sheetID)) {
|
|
@@ -65,12 +72,20 @@ function default_1(app) {
|
|
|
65
72
|
Object.defineProperty(prototype, 'adoptedStyleSheets', Object.assign(Object.assign({}, nativeAdoptedStyleSheetsDescriptor), { set: function (value) {
|
|
66
73
|
// @ts-ignore
|
|
67
74
|
const retVal = nativeAdoptedStyleSheetsDescriptor.set.call(this, value);
|
|
68
|
-
|
|
75
|
+
sendAdoptedStyleSheetsUpdate(this);
|
|
69
76
|
return retVal;
|
|
70
77
|
} }));
|
|
71
78
|
}
|
|
72
79
|
}
|
|
73
80
|
const patchContext = (context) => {
|
|
81
|
+
// @ts-ignore
|
|
82
|
+
if (context.__openreplay_adpss_patched__) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// @ts-ignore
|
|
87
|
+
context.__openreplay_adpss_patched__ = true;
|
|
88
|
+
}
|
|
74
89
|
patchAdoptedStyleSheets(context.Document.prototype);
|
|
75
90
|
patchAdoptedStyleSheets(context.ShadowRoot.prototype);
|
|
76
91
|
//@ts-ignore TODO: configure ts (use necessary lib)
|
|
@@ -93,20 +108,6 @@ function default_1(app) {
|
|
|
93
108
|
}
|
|
94
109
|
return replaceSync.call(this, text);
|
|
95
110
|
};
|
|
96
|
-
context.CSSStyleSheet.prototype.insertRule = function (rule, index = 0) {
|
|
97
|
-
const sheetID = styleSheetIDMap.get(this);
|
|
98
|
-
if (sheetID) {
|
|
99
|
-
app.send((0, messages_gen_js_1.AdoptedSSInsertRuleURLBased)(sheetID, rule, index, app.getBaseHref()));
|
|
100
|
-
}
|
|
101
|
-
return insertRule.call(this, rule, index);
|
|
102
|
-
};
|
|
103
|
-
context.CSSStyleSheet.prototype.deleteRule = function (index) {
|
|
104
|
-
const sheetID = styleSheetIDMap.get(this);
|
|
105
|
-
if (sheetID) {
|
|
106
|
-
app.send((0, messages_gen_js_1.AdoptedSSDeleteRule)(sheetID, index));
|
|
107
|
-
}
|
|
108
|
-
return deleteRule.call(this, index);
|
|
109
|
-
};
|
|
110
111
|
};
|
|
111
112
|
patchContext(window);
|
|
112
113
|
app.observer.attachContextCallback(patchContext);
|
|
@@ -116,11 +117,11 @@ function default_1(app) {
|
|
|
116
117
|
});
|
|
117
118
|
// So far main Document is not triggered with nodeCallbacks
|
|
118
119
|
app.attachStartCallback(() => {
|
|
119
|
-
|
|
120
|
+
sendAdoptedStyleSheetsUpdate(document);
|
|
120
121
|
});
|
|
121
122
|
app.nodes.attachNodeCallback((node) => {
|
|
122
123
|
if (hasAdoptedSS(node)) {
|
|
123
|
-
|
|
124
|
+
sendAdoptedStyleSheetsUpdate(node);
|
|
124
125
|
}
|
|
125
126
|
});
|
|
126
127
|
}
|
package/cjs/modules/cssrules.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const messages_gen_js_1 = require("../app/messages.gen.js");
|
|
4
4
|
const guards_js_1 = require("../app/guards.js");
|
|
5
|
+
const constructedStyleSheets_js_1 = require("./constructedStyleSheets.js");
|
|
5
6
|
function default_1(app) {
|
|
6
7
|
if (app === null) {
|
|
7
8
|
return;
|
|
@@ -10,42 +11,88 @@ function default_1(app) {
|
|
|
10
11
|
app.send((0, messages_gen_js_1.TechnicalInfo)('no_stylesheet_prototype_in_window', ''));
|
|
11
12
|
return;
|
|
12
13
|
}
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
14
|
+
const sendInserDeleteRule = app.safe((sheet, index, rule) => {
|
|
15
|
+
const sheetID = constructedStyleSheets_js_1.styleSheetIDMap.get(sheet);
|
|
16
|
+
if (!sheetID) {
|
|
17
|
+
// OK-case. Sheet haven't been registered yet. Rules will be sent on registration.
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (typeof rule === 'string') {
|
|
21
|
+
app.send((0, messages_gen_js_1.AdoptedSSInsertRuleURLBased)(sheetID, rule, index, app.getBaseHref()));
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
app.send((0, messages_gen_js_1.AdoptedSSDeleteRule)(sheetID, index));
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
// TODO: proper rule insertion/removal (how?)
|
|
28
|
+
const sendReplaceGroupingRule = app.safe((rule) => {
|
|
29
|
+
let topmostRule = rule;
|
|
30
|
+
while (topmostRule.parentRule) {
|
|
31
|
+
topmostRule = topmostRule.parentRule;
|
|
32
|
+
}
|
|
33
|
+
const sheet = topmostRule.parentStyleSheet;
|
|
34
|
+
if (!sheet) {
|
|
35
|
+
app.debug.warn('No parent StyleSheet found for', topmostRule, rule);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const sheetID = constructedStyleSheets_js_1.styleSheetIDMap.get(sheet);
|
|
39
|
+
if (!sheetID) {
|
|
40
|
+
app.debug.warn('No sheedID found for', sheet, constructedStyleSheets_js_1.styleSheetIDMap);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const cssText = topmostRule.cssText;
|
|
44
|
+
const ruleList = sheet.cssRules;
|
|
45
|
+
const idx = Array.from(ruleList).indexOf(topmostRule);
|
|
46
|
+
if (idx >= 0) {
|
|
47
|
+
app.send((0, messages_gen_js_1.AdoptedSSInsertRuleURLBased)(sheetID, cssText, idx, app.getBaseHref()));
|
|
48
|
+
app.send((0, messages_gen_js_1.AdoptedSSDeleteRule)(sheetID, idx + 1)); // Remove previous clone
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
app.debug.warn('Rule index not found in', sheet, topmostRule);
|
|
52
|
+
}
|
|
25
53
|
});
|
|
26
54
|
const patchContext = (context) => {
|
|
27
55
|
const { insertRule, deleteRule } = context.CSSStyleSheet.prototype;
|
|
56
|
+
const { insertRule: groupInsertRule, deleteRule: groupDeleteRule } = context.CSSGroupingRule.prototype;
|
|
28
57
|
context.CSSStyleSheet.prototype.insertRule = function (rule, index = 0) {
|
|
29
|
-
|
|
58
|
+
sendInserDeleteRule(this, index, rule);
|
|
30
59
|
return insertRule.call(this, rule, index);
|
|
31
60
|
};
|
|
32
61
|
context.CSSStyleSheet.prototype.deleteRule = function (index) {
|
|
33
|
-
|
|
62
|
+
sendInserDeleteRule(this, index);
|
|
34
63
|
return deleteRule.call(this, index);
|
|
35
64
|
};
|
|
65
|
+
context.CSSGroupingRule.prototype.insertRule = function (rule, index = 0) {
|
|
66
|
+
const result = groupInsertRule.call(this, rule, index);
|
|
67
|
+
sendReplaceGroupingRule(this);
|
|
68
|
+
return result;
|
|
69
|
+
};
|
|
70
|
+
context.CSSGroupingRule.prototype.deleteRule = function (index = 0) {
|
|
71
|
+
const result = groupDeleteRule.call(this, index);
|
|
72
|
+
sendReplaceGroupingRule(this);
|
|
73
|
+
return result;
|
|
74
|
+
};
|
|
36
75
|
};
|
|
37
76
|
patchContext(window);
|
|
38
77
|
app.observer.attachContextCallback(patchContext);
|
|
39
78
|
app.nodes.attachNodeCallback((node) => {
|
|
40
|
-
if (!(0, guards_js_1.hasTag)(node, 'STYLE') || !node.sheet) {
|
|
79
|
+
if (!((0, guards_js_1.hasTag)(node, 'STYLE') || (0, guards_js_1.hasTag)(node, 'style')) || !node.sheet) {
|
|
41
80
|
return;
|
|
42
81
|
}
|
|
43
82
|
if (node.textContent !== null && node.textContent.trim().length > 0) {
|
|
44
|
-
return; //
|
|
83
|
+
return; // Non-virtual styles captured by the observer as a text
|
|
84
|
+
}
|
|
85
|
+
const nodeID = app.nodes.getID(node);
|
|
86
|
+
if (!nodeID) {
|
|
87
|
+
return;
|
|
45
88
|
}
|
|
46
|
-
const
|
|
89
|
+
const sheet = node.sheet;
|
|
90
|
+
const sheetID = (0, constructedStyleSheets_js_1.nextID)();
|
|
91
|
+
constructedStyleSheets_js_1.styleSheetIDMap.set(sheet, sheetID);
|
|
92
|
+
app.send((0, messages_gen_js_1.AdoptedSSAddOwner)(sheetID, nodeID));
|
|
93
|
+
const rules = sheet.cssRules;
|
|
47
94
|
for (let i = 0; i < rules.length; i++) {
|
|
48
|
-
|
|
95
|
+
sendInserDeleteRule(sheet, i, rules[i].cssText);
|
|
49
96
|
}
|
|
50
97
|
});
|
|
51
98
|
}
|
package/cjs/modules/img.js
CHANGED
|
@@ -10,7 +10,7 @@ function resolveURL(url, location = document.location) {
|
|
|
10
10
|
}
|
|
11
11
|
else if (url.startsWith('http://') ||
|
|
12
12
|
url.startsWith('https://') ||
|
|
13
|
-
url.startsWith('data:') // any other possible value here?
|
|
13
|
+
url.startsWith('data:') // any other possible value here? https://bugzilla.mozilla.org/show_bug.cgi?id=1758035
|
|
14
14
|
) {
|
|
15
15
|
return url;
|
|
16
16
|
}
|
|
@@ -18,6 +18,10 @@ function resolveURL(url, location = document.location) {
|
|
|
18
18
|
return location.origin + location.pathname + url;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
+
// https://bugzilla.mozilla.org/show_bug.cgi?id=1607081
|
|
22
|
+
function isSVGInFireFox(url) {
|
|
23
|
+
return utils_js_1.IS_FIREFOX && (url.startsWith('data:image/svg+xml') || url.match(/.svg$|/i));
|
|
24
|
+
}
|
|
21
25
|
const PLACEHOLDER_SRC = 'https://static.openreplay.com/tracker/placeholder.jpeg';
|
|
22
26
|
function default_1(app) {
|
|
23
27
|
function sendPlaceholder(id, node) {
|
|
@@ -42,30 +46,34 @@ function default_1(app) {
|
|
|
42
46
|
app.send((0, messages_gen_js_1.SetNodeAttribute)(id, 'srcset', resolvedSrcset));
|
|
43
47
|
};
|
|
44
48
|
const sendSrc = function (id, img) {
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
if (img.src.length > utils_js_1.MAX_STR_LEN) {
|
|
50
|
+
sendPlaceholder(id, img);
|
|
51
|
+
}
|
|
52
|
+
app.send((0, messages_gen_js_1.SetNodeAttributeURLBased)(id, 'src', img.src, app.getBaseHref()));
|
|
47
53
|
};
|
|
48
|
-
const
|
|
49
|
-
const
|
|
54
|
+
const sendImgError = app.safe(function (img) {
|
|
55
|
+
const resolvedSrc = resolveURL(img.src || ''); // Src type is null sometimes. - is it true?
|
|
56
|
+
if ((0, utils_js_1.isURL)(resolvedSrc)) {
|
|
57
|
+
app.send((0, messages_gen_js_1.ResourceTiming)((0, utils_js_1.timestamp)(), 0, 0, 0, 0, 0, resolvedSrc, 'img'));
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
const sendImgAttrs = app.safe(function (img) {
|
|
61
|
+
const id = app.nodes.getID(img);
|
|
50
62
|
if (id === undefined) {
|
|
51
63
|
return;
|
|
52
64
|
}
|
|
53
|
-
|
|
54
|
-
if (!complete) {
|
|
65
|
+
if (!img.complete) {
|
|
55
66
|
return;
|
|
56
67
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if ((0, utils_js_1.isURL)(resolvedSrc)) {
|
|
60
|
-
app.send((0, messages_gen_js_1.ResourceTiming)((0, utils_js_1.timestamp)(), 0, 0, 0, 0, 0, resolvedSrc, 'img'));
|
|
61
|
-
}
|
|
68
|
+
if (img.naturalHeight === 0 && img.naturalWidth === 0 && !isSVGInFireFox(img.src)) {
|
|
69
|
+
sendImgError(img);
|
|
62
70
|
}
|
|
63
|
-
else if (
|
|
64
|
-
sendPlaceholder(id,
|
|
71
|
+
else if (app.sanitizer.isHidden(id) || app.sanitizer.isObscured(id)) {
|
|
72
|
+
sendPlaceholder(id, img);
|
|
65
73
|
}
|
|
66
74
|
else {
|
|
67
|
-
sendSrc(id,
|
|
68
|
-
sendSrcset(id,
|
|
75
|
+
sendSrc(id, img);
|
|
76
|
+
sendSrcset(id, img);
|
|
69
77
|
}
|
|
70
78
|
});
|
|
71
79
|
const observer = new MutationObserver((mutations) => {
|
|
@@ -92,9 +100,9 @@ function default_1(app) {
|
|
|
92
100
|
if (!(0, guards_js_1.hasTag)(node, 'IMG')) {
|
|
93
101
|
return;
|
|
94
102
|
}
|
|
95
|
-
app.nodes.
|
|
96
|
-
app.nodes.
|
|
97
|
-
sendImgAttrs
|
|
103
|
+
app.nodes.attachNodeListener(node, 'error', () => sendImgError(node));
|
|
104
|
+
app.nodes.attachNodeListener(node, 'load', () => sendImgAttrs(node));
|
|
105
|
+
sendImgAttrs(node);
|
|
98
106
|
observer.observe(node, { attributes: true, attributeFilter: ['src', 'srcset'] });
|
|
99
107
|
});
|
|
100
108
|
}
|
package/cjs/modules/input.js
CHANGED
|
@@ -80,10 +80,10 @@ function default_1(app, opts) {
|
|
|
80
80
|
function sendInputValue(id, node) {
|
|
81
81
|
let value = node.value;
|
|
82
82
|
let inputMode = options.defaultInputMode;
|
|
83
|
-
if (node.type === 'password' ||
|
|
83
|
+
if (node.type === 'password' || app.sanitizer.isHidden(id)) {
|
|
84
84
|
inputMode = 2 /* Hidden */;
|
|
85
85
|
}
|
|
86
|
-
else if (
|
|
86
|
+
else if (app.sanitizer.isObscured(id) ||
|
|
87
87
|
(inputMode === 0 /* Plain */ &&
|
|
88
88
|
((options.obscureInputNumbers && node.type !== 'date' && /\d\d\d\d/.test(value)) ||
|
|
89
89
|
(options.obscureInputDates && node.type === 'date') ||
|
package/cjs/modules/mouse.js
CHANGED
|
@@ -98,11 +98,13 @@ function default_1(app) {
|
|
|
98
98
|
let mousePositionChanged = false;
|
|
99
99
|
let mouseTarget = null;
|
|
100
100
|
let mouseTargetTime = 0;
|
|
101
|
+
let selectorMap = {};
|
|
101
102
|
app.attachStopCallback(() => {
|
|
102
103
|
mousePositionX = -1;
|
|
103
104
|
mousePositionY = -1;
|
|
104
105
|
mousePositionChanged = false;
|
|
105
106
|
mouseTarget = null;
|
|
107
|
+
selectorMap = {};
|
|
106
108
|
});
|
|
107
109
|
const sendMouseMove = () => {
|
|
108
110
|
if (mousePositionChanged) {
|
|
@@ -110,25 +112,27 @@ function default_1(app) {
|
|
|
110
112
|
mousePositionChanged = false;
|
|
111
113
|
}
|
|
112
114
|
};
|
|
113
|
-
const patchDocument = (document) => {
|
|
114
|
-
const selectorMap = {};
|
|
115
|
+
const patchDocument = (document, topframe = false) => {
|
|
115
116
|
function getSelector(id, target) {
|
|
116
117
|
return (selectorMap[id] = selectorMap[id] || _getSelector(target, document));
|
|
117
118
|
}
|
|
118
|
-
|
|
119
|
+
const attachListener = topframe
|
|
120
|
+
? app.attachEventListener.bind(app) // attached/removed on start/stop
|
|
121
|
+
: app.nodes.attachNodeListener.bind(app.nodes); // attached/removed on node register/unregister
|
|
122
|
+
attachListener(document.documentElement, 'mouseover', (e) => {
|
|
119
123
|
const target = getTarget(e.target, document);
|
|
120
124
|
if (target !== mouseTarget) {
|
|
121
125
|
mouseTarget = target;
|
|
122
126
|
mouseTargetTime = performance.now();
|
|
123
127
|
}
|
|
124
128
|
});
|
|
125
|
-
|
|
126
|
-
const
|
|
129
|
+
attachListener(document, 'mousemove', (e) => {
|
|
130
|
+
const [left, top] = app.observer.getDocumentOffset(document); // MBTODO?: document-id related message
|
|
127
131
|
mousePositionX = e.clientX + left;
|
|
128
132
|
mousePositionY = e.clientY + top;
|
|
129
133
|
mousePositionChanged = true;
|
|
130
134
|
}, false);
|
|
131
|
-
|
|
135
|
+
attachListener(document, 'click', (e) => {
|
|
132
136
|
const target = getTarget(e.target, document);
|
|
133
137
|
if ((!e.clientX && !e.clientY) || target === null) {
|
|
134
138
|
return;
|
|
@@ -146,7 +150,7 @@ function default_1(app) {
|
|
|
146
150
|
patchDocument(node);
|
|
147
151
|
}
|
|
148
152
|
});
|
|
149
|
-
patchDocument(document);
|
|
153
|
+
patchDocument(document, true);
|
|
150
154
|
app.ticker.attach(sendMouseMove, 10);
|
|
151
155
|
}
|
|
152
156
|
exports.default = default_1;
|
package/cjs/modules/scroll.js
CHANGED
|
@@ -2,21 +2,34 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const messages_gen_js_1 = require("../app/messages.gen.js");
|
|
4
4
|
const guards_js_1 = require("../app/guards.js");
|
|
5
|
+
function getDocumentScroll(doc) {
|
|
6
|
+
const win = doc.defaultView;
|
|
7
|
+
return [
|
|
8
|
+
(win && win.pageXOffset) ||
|
|
9
|
+
(doc.documentElement && doc.documentElement.scrollLeft) ||
|
|
10
|
+
(doc.body && doc.body.scrollLeft) ||
|
|
11
|
+
0,
|
|
12
|
+
(win && win.pageYOffset) ||
|
|
13
|
+
(doc.documentElement && doc.documentElement.scrollTop) ||
|
|
14
|
+
(doc.body && doc.body.scrollTop) ||
|
|
15
|
+
0,
|
|
16
|
+
];
|
|
17
|
+
}
|
|
5
18
|
function default_1(app) {
|
|
6
19
|
let documentScroll = false;
|
|
7
20
|
const nodeScroll = new Map();
|
|
8
21
|
function setNodeScroll(target) {
|
|
9
|
-
if (
|
|
22
|
+
if (!(0, guards_js_1.isNode)(target)) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if ((0, guards_js_1.isElementNode)(target)) {
|
|
10
26
|
nodeScroll.set(target, [target.scrollLeft, target.scrollTop]);
|
|
11
27
|
}
|
|
28
|
+
if ((0, guards_js_1.isDocument)(target)) {
|
|
29
|
+
nodeScroll.set(target, getDocumentScroll(target));
|
|
30
|
+
}
|
|
12
31
|
}
|
|
13
|
-
const sendSetViewportScroll = app.safe(() => app.send((0, messages_gen_js_1.SetViewportScroll)(
|
|
14
|
-
(document.documentElement && document.documentElement.scrollLeft) ||
|
|
15
|
-
(document.body && document.body.scrollLeft) ||
|
|
16
|
-
0, window.pageYOffset ||
|
|
17
|
-
(document.documentElement && document.documentElement.scrollTop) ||
|
|
18
|
-
(document.body && document.body.scrollTop) ||
|
|
19
|
-
0)));
|
|
32
|
+
const sendSetViewportScroll = app.safe(() => app.send((0, messages_gen_js_1.SetViewportScroll)(...getDocumentScroll(document))));
|
|
20
33
|
const sendSetNodeScroll = app.safe((s, node) => {
|
|
21
34
|
const id = app.nodes.getID(node);
|
|
22
35
|
if (id !== undefined) {
|
|
@@ -29,12 +42,19 @@ function default_1(app) {
|
|
|
29
42
|
nodeScroll.clear();
|
|
30
43
|
});
|
|
31
44
|
app.nodes.attachNodeCallback((node, isStart) => {
|
|
32
|
-
|
|
33
|
-
|
|
45
|
+
// MBTODO: iterate over all the nodes on start instead of using isStart hack
|
|
46
|
+
if (isStart) {
|
|
47
|
+
if ((0, guards_js_1.isElementNode)(node) && node.scrollLeft + node.scrollTop > 0) {
|
|
48
|
+
nodeScroll.set(node, [node.scrollLeft, node.scrollTop]);
|
|
49
|
+
}
|
|
50
|
+
else if ((0, guards_js_1.isDocument)(node)) {
|
|
51
|
+
// DRY somehow?
|
|
52
|
+
nodeScroll.set(node, getDocumentScroll(node));
|
|
53
|
+
}
|
|
34
54
|
}
|
|
35
|
-
|
|
55
|
+
if ((0, guards_js_1.isRootNode)(node)) {
|
|
36
56
|
// scroll is not-composed event (https://javascript.info/shadow-dom-events)
|
|
37
|
-
app.
|
|
57
|
+
app.nodes.attachNodeListener(node, 'scroll', (e) => {
|
|
38
58
|
setNodeScroll(e.target);
|
|
39
59
|
});
|
|
40
60
|
}
|
package/cjs/utils.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
export declare
|
|
1
|
+
export declare const IN_BROWSER: boolean;
|
|
2
|
+
export declare const IS_FIREFOX: false | RegExpMatchArray | null;
|
|
3
|
+
export declare const MAX_STR_LEN = 100000;
|
|
4
|
+
export declare const timestamp: () => number;
|
|
2
5
|
export declare const stars: (str: string) => string;
|
|
3
6
|
export declare function normSpaces(str: string): string;
|
|
4
7
|
export declare function isURL(s: string): boolean;
|
|
5
|
-
export declare const IN_BROWSER: boolean;
|
|
6
8
|
export declare const DOCS_HOST = "https://docs.openreplay.com";
|
|
7
9
|
export declare function deprecationWarn(nameOfFeature: string, useInstead: string, docsPath?: string): void;
|
|
8
10
|
export declare function getLabelAttribute(e: Element): string | null;
|
|
9
|
-
export declare function hasOpenreplayAttribute(e: Element,
|
|
11
|
+
export declare function hasOpenreplayAttribute(e: Element, attr: string): boolean;
|
package/cjs/utils.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.hasOpenreplayAttribute = exports.getLabelAttribute = exports.deprecationWarn = exports.DOCS_HOST = exports.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
exports.
|
|
3
|
+
exports.hasOpenreplayAttribute = exports.getLabelAttribute = exports.deprecationWarn = exports.DOCS_HOST = exports.isURL = exports.normSpaces = exports.stars = exports.timestamp = exports.MAX_STR_LEN = exports.IS_FIREFOX = exports.IN_BROWSER = void 0;
|
|
4
|
+
const DEPRECATED_ATTRS = { htmlmasked: 'hidden', masked: 'obscured' };
|
|
5
|
+
exports.IN_BROWSER = !(typeof window === 'undefined');
|
|
6
|
+
exports.IS_FIREFOX = exports.IN_BROWSER && navigator.userAgent.match(/firefox|fxios/i);
|
|
7
|
+
exports.MAX_STR_LEN = 1e5;
|
|
8
|
+
const navigationStart = (exports.IN_BROWSER && performance.timing.navigationStart) || performance.timeOrigin;
|
|
9
|
+
// performance.now() is buggy in some browsers
|
|
10
|
+
exports.timestamp = exports.IN_BROWSER && performance.now() && navigationStart
|
|
11
|
+
? () => Math.round(performance.now() + navigationStart)
|
|
12
|
+
: () => Date.now();
|
|
8
13
|
exports.stars = 'repeat' in String.prototype
|
|
9
14
|
? (str) => '*'.repeat(str.length)
|
|
10
15
|
: (str) => str.replace(/./g, '*');
|
|
@@ -17,7 +22,6 @@ function isURL(s) {
|
|
|
17
22
|
return s.startsWith('https://') || s.startsWith('http://');
|
|
18
23
|
}
|
|
19
24
|
exports.isURL = isURL;
|
|
20
|
-
exports.IN_BROWSER = !(typeof window === 'undefined');
|
|
21
25
|
// TODO: JOIN IT WITH LOGGER somehow (use logging decorators?); Don't forget about index.js loggin when there is no logger instance.
|
|
22
26
|
exports.DOCS_HOST = 'https://docs.openreplay.com';
|
|
23
27
|
const warnedFeatures = {};
|
|
@@ -41,14 +45,15 @@ function getLabelAttribute(e) {
|
|
|
41
45
|
return value;
|
|
42
46
|
}
|
|
43
47
|
exports.getLabelAttribute = getLabelAttribute;
|
|
44
|
-
function hasOpenreplayAttribute(e,
|
|
45
|
-
const newName = `data-openreplay-${
|
|
48
|
+
function hasOpenreplayAttribute(e, attr) {
|
|
49
|
+
const newName = `data-openreplay-${attr}`;
|
|
46
50
|
if (e.hasAttribute(newName)) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
// @ts-ignore
|
|
52
|
+
if (DEPRECATED_ATTRS[attr]) {
|
|
53
|
+
deprecationWarn(`"${newName}" attribute`,
|
|
54
|
+
// @ts-ignore
|
|
55
|
+
`"${DEPRECATED_ATTRS[attr]}" attribute`, '/installation/sanitize-data');
|
|
56
|
+
}
|
|
52
57
|
return true;
|
|
53
58
|
}
|
|
54
59
|
return false;
|
package/lib/app/guards.d.ts
CHANGED
package/lib/app/guards.js
CHANGED
package/lib/app/index.d.ts
CHANGED
|
@@ -77,7 +77,7 @@ export default class App {
|
|
|
77
77
|
private _debug;
|
|
78
78
|
send(message: Message, urgent?: boolean): void;
|
|
79
79
|
private commit;
|
|
80
|
-
safe<T extends (...args: any[]) => void>(fn: T): T;
|
|
80
|
+
safe<T extends (this: any, ...args: any[]) => void>(fn: T): T;
|
|
81
81
|
attachCommitCallback(cb: CommitCallback): void;
|
|
82
82
|
attachStartCallback(cb: StartCallback, useSafe?: boolean): void;
|
|
83
83
|
attachStopCallback(cb: () => any, useSafe?: boolean): void;
|