@openreplay/tracker 3.5.12 → 3.5.14
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 +18 -0
- package/cjs/app/guards.js +24 -0
- package/cjs/app/index.d.ts +5 -1
- package/cjs/app/index.js +55 -32
- package/cjs/app/nodes.d.ts +3 -3
- package/cjs/app/nodes.js +2 -2
- package/cjs/app/observer/observer.d.ts +1 -2
- package/cjs/app/observer/observer.js +73 -60
- package/cjs/app/observer/top_observer.js +3 -3
- package/cjs/app/sanitizer.d.ts +3 -1
- package/cjs/app/sanitizer.js +13 -2
- package/cjs/app/session.d.ts +2 -7
- package/cjs/app/session.js +24 -37
- package/cjs/index.js +2 -2
- package/cjs/modules/console.d.ts +1 -1
- package/cjs/modules/console.js +2 -1
- package/cjs/modules/cssrules.d.ts +1 -1
- package/cjs/modules/cssrules.js +2 -4
- package/cjs/modules/exception.d.ts +1 -1
- package/cjs/modules/img.d.ts +1 -1
- package/cjs/modules/img.js +14 -6
- package/cjs/modules/input.d.ts +2 -1
- package/cjs/modules/input.js +18 -20
- package/cjs/modules/longtasks.d.ts +1 -1
- package/cjs/modules/mouse.d.ts +1 -1
- package/cjs/modules/mouse.js +3 -2
- package/cjs/modules/performance.d.ts +1 -1
- package/cjs/modules/scroll.d.ts +1 -1
- package/cjs/modules/scroll.js +3 -2
- package/cjs/modules/timing.d.ts +1 -1
- package/cjs/modules/timing.js +2 -1
- package/cjs/modules/viewport.d.ts +1 -1
- package/lib/app/guards.d.ts +18 -0
- package/lib/app/guards.js +16 -0
- package/lib/app/index.d.ts +5 -1
- package/lib/app/index.js +56 -33
- package/lib/app/nodes.d.ts +3 -3
- package/lib/app/nodes.js +2 -2
- package/lib/app/observer/observer.d.ts +1 -2
- package/lib/app/observer/observer.js +70 -57
- package/lib/app/observer/top_observer.js +3 -3
- package/lib/app/sanitizer.d.ts +3 -1
- package/lib/app/sanitizer.js +13 -2
- package/lib/app/session.d.ts +2 -7
- package/lib/app/session.js +24 -37
- package/lib/common/tsconfig.tsbuildinfo +1 -1
- package/lib/index.js +2 -2
- package/lib/modules/console.d.ts +1 -1
- package/lib/modules/console.js +2 -1
- package/lib/modules/cssrules.d.ts +1 -1
- package/lib/modules/cssrules.js +2 -4
- package/lib/modules/exception.d.ts +1 -1
- package/lib/modules/img.d.ts +1 -1
- package/lib/modules/img.js +14 -6
- package/lib/modules/input.d.ts +2 -1
- package/lib/modules/input.js +18 -20
- package/lib/modules/longtasks.d.ts +1 -1
- package/lib/modules/mouse.d.ts +1 -1
- package/lib/modules/mouse.js +3 -2
- package/lib/modules/performance.d.ts +1 -1
- package/lib/modules/scroll.d.ts +1 -1
- package/lib/modules/scroll.js +3 -2
- package/lib/modules/timing.d.ts +1 -1
- package/lib/modules/timing.js +2 -1
- package/lib/modules/viewport.d.ts +1 -1
- package/package.json +7 -7
- package/cjs/app/context.d.ts +0 -18
- package/cjs/app/context.js +0 -73
- package/lib/app/context.d.ts +0 -18
- package/lib/app/context.js +0 -68
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const messages_js_1 = require("../../common/messages.js");
|
|
4
|
-
const
|
|
5
|
-
function isSVGElement(node) {
|
|
6
|
-
return node.namespaceURI === 'http://www.w3.org/2000/svg';
|
|
7
|
-
}
|
|
4
|
+
const guards_js_1 = require("../guards.js");
|
|
8
5
|
function isIgnored(node) {
|
|
9
|
-
if ((0,
|
|
6
|
+
if ((0, guards_js_1.isTextNode)(node)) {
|
|
10
7
|
return false;
|
|
11
8
|
}
|
|
12
|
-
if (!(0,
|
|
9
|
+
if (!(0, guards_js_1.isElementNode)(node)) {
|
|
13
10
|
return true;
|
|
14
11
|
}
|
|
15
12
|
const tag = node.tagName.toUpperCase();
|
|
@@ -24,30 +21,37 @@ function isIgnored(node) {
|
|
|
24
21
|
tag === 'TITLE' ||
|
|
25
22
|
tag === 'BASE');
|
|
26
23
|
}
|
|
27
|
-
function isRootNode(node) {
|
|
28
|
-
return (0, context_js_1.isInstance)(node, Document) || (0, context_js_1.isInstance)(node, ShadowRoot);
|
|
29
|
-
}
|
|
30
24
|
function isObservable(node) {
|
|
31
|
-
if (isRootNode(node)) {
|
|
25
|
+
if ((0, guards_js_1.isRootNode)(node)) {
|
|
32
26
|
return true;
|
|
33
27
|
}
|
|
34
28
|
return !isIgnored(node);
|
|
35
29
|
}
|
|
30
|
+
/*
|
|
31
|
+
TODO:
|
|
32
|
+
- fix unbinding logic + send all removals first (ensure sequence is correct)
|
|
33
|
+
- use document as a 0-node in the upper context (should be updated in player at first)
|
|
34
|
+
*/
|
|
35
|
+
var RecentsType;
|
|
36
|
+
(function (RecentsType) {
|
|
37
|
+
RecentsType[RecentsType["New"] = 0] = "New";
|
|
38
|
+
RecentsType[RecentsType["Removed"] = 1] = "Removed";
|
|
39
|
+
RecentsType[RecentsType["Changed"] = 2] = "Changed";
|
|
40
|
+
})(RecentsType || (RecentsType = {}));
|
|
36
41
|
class Observer {
|
|
37
42
|
constructor(app, isTopContext = false) {
|
|
38
43
|
this.app = app;
|
|
39
44
|
this.isTopContext = isTopContext;
|
|
40
45
|
this.commited = [];
|
|
41
|
-
this.recents =
|
|
42
|
-
this.myNodes = [];
|
|
46
|
+
this.recents = new Map();
|
|
43
47
|
this.indexes = [];
|
|
44
|
-
this.
|
|
48
|
+
this.attributesMap = new Map();
|
|
45
49
|
this.textSet = new Set();
|
|
46
50
|
this.observer = new MutationObserver(this.app.safe((mutations) => {
|
|
47
|
-
for (const mutation of mutations) {
|
|
51
|
+
for (const mutation of mutations) { // mutations order is sequential
|
|
48
52
|
const target = mutation.target;
|
|
49
53
|
const type = mutation.type;
|
|
50
|
-
if (!isObservable(target)
|
|
54
|
+
if (!isObservable(target)) {
|
|
51
55
|
continue;
|
|
52
56
|
}
|
|
53
57
|
if (type === 'childList') {
|
|
@@ -63,17 +67,17 @@ class Observer {
|
|
|
63
67
|
if (id === undefined) {
|
|
64
68
|
continue;
|
|
65
69
|
}
|
|
66
|
-
if (
|
|
67
|
-
this.recents
|
|
70
|
+
if (!this.recents.has(id)) {
|
|
71
|
+
this.recents.set(id, RecentsType.Changed); // TODO only when altered
|
|
68
72
|
}
|
|
69
73
|
if (type === 'attributes') {
|
|
70
74
|
const name = mutation.attributeName;
|
|
71
75
|
if (name === null) {
|
|
72
76
|
continue;
|
|
73
77
|
}
|
|
74
|
-
let attr = this.
|
|
78
|
+
let attr = this.attributesMap.get(id);
|
|
75
79
|
if (attr === undefined) {
|
|
76
|
-
this.
|
|
80
|
+
this.attributesMap.set(id, attr = new Set());
|
|
77
81
|
}
|
|
78
82
|
attr.add(name);
|
|
79
83
|
continue;
|
|
@@ -88,13 +92,13 @@ class Observer {
|
|
|
88
92
|
}
|
|
89
93
|
clear() {
|
|
90
94
|
this.commited.length = 0;
|
|
91
|
-
this.recents.
|
|
95
|
+
this.recents.clear();
|
|
92
96
|
this.indexes.length = 1;
|
|
93
|
-
this.
|
|
97
|
+
this.attributesMap.clear();
|
|
94
98
|
this.textSet.clear();
|
|
95
99
|
}
|
|
96
100
|
sendNodeAttribute(id, node, name, value) {
|
|
97
|
-
if (isSVGElement(node)) {
|
|
101
|
+
if ((0, guards_js_1.isSVGElement)(node)) {
|
|
98
102
|
if (name.substr(0, 6) === 'xlink:') {
|
|
99
103
|
name = name.substr(6);
|
|
100
104
|
}
|
|
@@ -121,7 +125,7 @@ class Observer {
|
|
|
121
125
|
return;
|
|
122
126
|
}
|
|
123
127
|
if (name === 'value' &&
|
|
124
|
-
(0,
|
|
128
|
+
(0, guards_js_1.hasTag)(node, "INPUT") &&
|
|
125
129
|
node.type !== 'button' &&
|
|
126
130
|
node.type !== 'reset' &&
|
|
127
131
|
node.type !== 'submit') {
|
|
@@ -131,7 +135,7 @@ class Observer {
|
|
|
131
135
|
this.app.send(new messages_js_1.RemoveNodeAttribute(id, name));
|
|
132
136
|
return;
|
|
133
137
|
}
|
|
134
|
-
if (name === 'style' || name === 'href' && (0,
|
|
138
|
+
if (name === 'style' || name === 'href' && (0, guards_js_1.hasTag)(node, "LINK")) {
|
|
135
139
|
this.app.send(new messages_js_1.SetNodeAttributeURLBased(id, name, value, this.app.getBaseHref()));
|
|
136
140
|
return;
|
|
137
141
|
}
|
|
@@ -141,7 +145,7 @@ class Observer {
|
|
|
141
145
|
this.app.send(new messages_js_1.SetNodeAttribute(id, name, value));
|
|
142
146
|
}
|
|
143
147
|
sendNodeData(id, parentElement, data) {
|
|
144
|
-
if ((0,
|
|
148
|
+
if ((0, guards_js_1.hasTag)(parentElement, "STYLE") || (0, guards_js_1.hasTag)(parentElement, "style")) {
|
|
145
149
|
this.app.send(new messages_js_1.SetCSSDataURLBased(id, data, this.app.getBaseHref()));
|
|
146
150
|
return;
|
|
147
151
|
}
|
|
@@ -149,10 +153,13 @@ class Observer {
|
|
|
149
153
|
this.app.send(new messages_js_1.SetNodeData(id, data));
|
|
150
154
|
}
|
|
151
155
|
bindNode(node) {
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
+
const [id, isNew] = this.app.nodes.registerNode(node);
|
|
157
|
+
if (isNew) {
|
|
158
|
+
this.recents.set(id, RecentsType.New);
|
|
159
|
+
}
|
|
160
|
+
else if (!this.recents.has(id)) {
|
|
161
|
+
this.recents.set(id, RecentsType.Removed);
|
|
162
|
+
}
|
|
156
163
|
}
|
|
157
164
|
bindTree(node) {
|
|
158
165
|
if (!isObservable(node)) {
|
|
@@ -172,20 +179,21 @@ class Observer {
|
|
|
172
179
|
}
|
|
173
180
|
unbindNode(node) {
|
|
174
181
|
const id = this.app.nodes.unregisterNode(node);
|
|
175
|
-
if (id !== undefined && this.recents
|
|
182
|
+
if (id !== undefined && this.recents.get(id) === RecentsType.Removed) {
|
|
176
183
|
this.app.send(new messages_js_1.RemoveNode(id));
|
|
177
184
|
}
|
|
178
185
|
}
|
|
186
|
+
// A top-consumption function on the infinite lists test. (~1% of performance resources)
|
|
179
187
|
_commitNode(id, node) {
|
|
180
|
-
if (isRootNode(node)) {
|
|
188
|
+
if ((0, guards_js_1.isRootNode)(node)) {
|
|
181
189
|
return true;
|
|
182
190
|
}
|
|
183
191
|
const parent = node.parentNode;
|
|
184
192
|
let parentID;
|
|
185
193
|
// Disable parent check for the upper context HTMLHtmlElement, because it is root there... (before)
|
|
186
194
|
// TODO: get rid of "special" cases (there is an issue with CreateDocument altered behaviour though)
|
|
187
|
-
// TODO: Clean the logic (though now it workd fine)
|
|
188
|
-
if (!(0,
|
|
195
|
+
// TODO: Clean the logic (though now it workd fine)
|
|
196
|
+
if (!(0, guards_js_1.hasTag)(node, "HTML") || !this.isTopContext) {
|
|
189
197
|
if (parent === null) {
|
|
190
198
|
this.unbindNode(node);
|
|
191
199
|
return false;
|
|
@@ -200,7 +208,11 @@ class Observer {
|
|
|
200
208
|
return false;
|
|
201
209
|
}
|
|
202
210
|
this.app.sanitizer.handleNode(id, parentID, node);
|
|
211
|
+
if (this.app.sanitizer.isMaskedContainer(parentID)) {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
203
214
|
}
|
|
215
|
+
// From here parentID === undefined if node is top context HTML node
|
|
204
216
|
let sibling = node.previousSibling;
|
|
205
217
|
while (sibling !== null) {
|
|
206
218
|
const siblingID = this.app.nodes.getID(sibling);
|
|
@@ -212,36 +224,45 @@ class Observer {
|
|
|
212
224
|
sibling = sibling.previousSibling;
|
|
213
225
|
}
|
|
214
226
|
if (sibling === null) {
|
|
215
|
-
this.indexes[id] = 0;
|
|
227
|
+
this.indexes[id] = 0;
|
|
216
228
|
}
|
|
217
|
-
const
|
|
229
|
+
const recentsType = this.recents.get(id);
|
|
230
|
+
const isNew = recentsType === RecentsType.New;
|
|
218
231
|
const index = this.indexes[id];
|
|
219
232
|
if (index === undefined) {
|
|
220
233
|
throw 'commitNode: missing node index';
|
|
221
234
|
}
|
|
222
|
-
if (isNew
|
|
223
|
-
if ((0,
|
|
235
|
+
if (isNew) {
|
|
236
|
+
if ((0, guards_js_1.isElementNode)(node)) {
|
|
237
|
+
let el = node;
|
|
224
238
|
if (parentID !== undefined) {
|
|
225
|
-
this.app.
|
|
239
|
+
if (this.app.sanitizer.isMaskedContainer(id)) {
|
|
240
|
+
const width = el.clientWidth;
|
|
241
|
+
const height = el.clientHeight;
|
|
242
|
+
el = node.cloneNode();
|
|
243
|
+
el.style.width = width + 'px';
|
|
244
|
+
el.style.height = height + 'px';
|
|
245
|
+
}
|
|
246
|
+
this.app.send(new messages_js_1.CreateElementNode(id, parentID, index, el.tagName, (0, guards_js_1.isSVGElement)(node)));
|
|
226
247
|
}
|
|
227
|
-
for (let i = 0; i <
|
|
228
|
-
const attr =
|
|
229
|
-
this.sendNodeAttribute(id,
|
|
248
|
+
for (let i = 0; i < el.attributes.length; i++) {
|
|
249
|
+
const attr = el.attributes[i];
|
|
250
|
+
this.sendNodeAttribute(id, el, attr.nodeName, attr.value);
|
|
230
251
|
}
|
|
231
252
|
}
|
|
232
|
-
else if ((0,
|
|
253
|
+
else if ((0, guards_js_1.isTextNode)(node)) {
|
|
233
254
|
// for text node id != 0, hence parentID !== undefined and parent is Element
|
|
234
255
|
this.app.send(new messages_js_1.CreateTextNode(id, parentID, index));
|
|
235
256
|
this.sendNodeData(id, parent, node.data);
|
|
236
257
|
}
|
|
237
258
|
return true;
|
|
238
259
|
}
|
|
239
|
-
if (
|
|
260
|
+
if (recentsType === RecentsType.Removed && parentID !== undefined) {
|
|
240
261
|
this.app.send(new messages_js_1.MoveNode(id, parentID, index));
|
|
241
262
|
}
|
|
242
|
-
const attr = this.
|
|
263
|
+
const attr = this.attributesMap.get(id);
|
|
243
264
|
if (attr !== undefined) {
|
|
244
|
-
if (!(0,
|
|
265
|
+
if (!(0, guards_js_1.isElementNode)(node)) {
|
|
245
266
|
throw 'commitNode: node is not an element';
|
|
246
267
|
}
|
|
247
268
|
for (const name of attr) {
|
|
@@ -249,7 +270,7 @@ class Observer {
|
|
|
249
270
|
}
|
|
250
271
|
}
|
|
251
272
|
if (this.textSet.has(id)) {
|
|
252
|
-
if (!(0,
|
|
273
|
+
if (!(0, guards_js_1.isTextNode)(node)) {
|
|
253
274
|
throw 'commitNode: node is not a text';
|
|
254
275
|
}
|
|
255
276
|
// for text node id != 0, hence parent is Element
|
|
@@ -268,21 +289,14 @@ class Observer {
|
|
|
268
289
|
}
|
|
269
290
|
return (this.commited[id] = this._commitNode(id, node));
|
|
270
291
|
}
|
|
271
|
-
commitNodes() {
|
|
292
|
+
commitNodes(isStart = false) {
|
|
272
293
|
let node;
|
|
273
|
-
|
|
274
|
-
// TODO: make things/logic nice here.
|
|
275
|
-
// commit required in any case if recents[id] true or false (in case of unbinding) or undefined (in case of attr change).
|
|
276
|
-
// Possible solution: separate new node commit (recents) and new attribute/move node commit
|
|
277
|
-
// Otherwise commitNode is called on each node, which might be a lot
|
|
278
|
-
if (!this.myNodes[id]) {
|
|
279
|
-
continue;
|
|
280
|
-
}
|
|
294
|
+
this.recents.forEach((type, id) => {
|
|
281
295
|
this.commitNode(id);
|
|
282
|
-
if (
|
|
283
|
-
this.app.nodes.callNodeCallbacks(node);
|
|
296
|
+
if (type === RecentsType.New && (node = this.app.nodes.getNode(id))) {
|
|
297
|
+
this.app.nodes.callNodeCallbacks(node, isStart);
|
|
284
298
|
}
|
|
285
|
-
}
|
|
299
|
+
});
|
|
286
300
|
this.clear();
|
|
287
301
|
}
|
|
288
302
|
// ISSSUE
|
|
@@ -297,12 +311,11 @@ class Observer {
|
|
|
297
311
|
});
|
|
298
312
|
this.bindTree(nodeToBind);
|
|
299
313
|
beforeCommit(this.app.nodes.getID(node));
|
|
300
|
-
this.commitNodes();
|
|
314
|
+
this.commitNodes(true);
|
|
301
315
|
}
|
|
302
316
|
disconnect() {
|
|
303
317
|
this.observer.disconnect();
|
|
304
318
|
this.clear();
|
|
305
|
-
this.myNodes.length = 0;
|
|
306
319
|
}
|
|
307
320
|
}
|
|
308
321
|
exports.default = Observer;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const observer_js_1 = require("./observer.js");
|
|
4
|
-
const
|
|
4
|
+
const guards_js_1 = require("../guards.js");
|
|
5
5
|
const iframe_observer_js_1 = require("./iframe_observer.js");
|
|
6
6
|
const shadow_root_observer_js_1 = require("./shadow_root_observer.js");
|
|
7
7
|
const messages_js_1 = require("../../common/messages.js");
|
|
@@ -17,7 +17,7 @@ class TopObserver extends observer_js_1.default {
|
|
|
17
17
|
}, options);
|
|
18
18
|
// IFrames
|
|
19
19
|
this.app.nodes.attachNodeCallback(node => {
|
|
20
|
-
if ((0,
|
|
20
|
+
if ((0, guards_js_1.hasTag)(node, "IFRAME") &&
|
|
21
21
|
((this.options.captureIFrames && !(0, utils_js_1.hasOpenreplayAttribute)(node, "obscured"))
|
|
22
22
|
|| (0, utils_js_1.hasOpenreplayAttribute)(node, "capture"))) {
|
|
23
23
|
this.handleIframe(node);
|
|
@@ -25,7 +25,7 @@ class TopObserver extends observer_js_1.default {
|
|
|
25
25
|
});
|
|
26
26
|
// ShadowDOM
|
|
27
27
|
this.app.nodes.attachNodeCallback(node => {
|
|
28
|
-
if ((0,
|
|
28
|
+
if ((0, guards_js_1.isElementNode)(node) && node.shadowRoot !== null) {
|
|
29
29
|
this.handleShadowRoot(node.shadowRoot);
|
|
30
30
|
}
|
|
31
31
|
});
|
package/cjs/app/sanitizer.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import App from "./index.js";
|
|
1
|
+
import type App from "./index.js";
|
|
2
2
|
export interface Options {
|
|
3
3
|
obscureTextEmails: boolean;
|
|
4
4
|
obscureTextNumbers: boolean;
|
|
@@ -6,11 +6,13 @@ export interface Options {
|
|
|
6
6
|
export default class Sanitizer {
|
|
7
7
|
private readonly app;
|
|
8
8
|
private readonly masked;
|
|
9
|
+
private readonly maskedContainers;
|
|
9
10
|
private readonly options;
|
|
10
11
|
constructor(app: App, options: Partial<Options>);
|
|
11
12
|
handleNode(id: number, parentID: number, node: Node): void;
|
|
12
13
|
sanitize(id: number, data: string): string;
|
|
13
14
|
isMasked(id: number): boolean;
|
|
15
|
+
isMaskedContainer(id: number): boolean;
|
|
14
16
|
getInnerTextSecure(el: HTMLElement): string;
|
|
15
17
|
clear(): void;
|
|
16
18
|
}
|
package/cjs/app/sanitizer.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const utils_js_1 = require("../utils.js");
|
|
4
|
-
const
|
|
4
|
+
const guards_js_1 = require("./guards.js");
|
|
5
5
|
class Sanitizer {
|
|
6
6
|
constructor(app, options) {
|
|
7
7
|
this.app = app;
|
|
8
8
|
this.masked = new Set();
|
|
9
|
+
this.maskedContainers = new Set();
|
|
9
10
|
this.options = Object.assign({
|
|
10
11
|
obscureTextEmails: true,
|
|
11
12
|
obscureTextNumbers: false,
|
|
@@ -13,9 +14,15 @@ class Sanitizer {
|
|
|
13
14
|
}
|
|
14
15
|
handleNode(id, parentID, node) {
|
|
15
16
|
if (this.masked.has(parentID) ||
|
|
16
|
-
((0,
|
|
17
|
+
((0, guards_js_1.isElementNode)(node) &&
|
|
18
|
+
(0, utils_js_1.hasOpenreplayAttribute)(node, 'masked'))) {
|
|
17
19
|
this.masked.add(id);
|
|
18
20
|
}
|
|
21
|
+
if (this.maskedContainers.has(parentID) ||
|
|
22
|
+
((0, guards_js_1.isElementNode)(node) &&
|
|
23
|
+
(0, utils_js_1.hasOpenreplayAttribute)(node, 'htmlmasked'))) {
|
|
24
|
+
this.maskedContainers.add(id);
|
|
25
|
+
}
|
|
19
26
|
}
|
|
20
27
|
sanitize(id, data) {
|
|
21
28
|
if (this.masked.has(id)) {
|
|
@@ -33,6 +40,9 @@ class Sanitizer {
|
|
|
33
40
|
isMasked(id) {
|
|
34
41
|
return this.masked.has(id);
|
|
35
42
|
}
|
|
43
|
+
isMaskedContainer(id) {
|
|
44
|
+
return this.maskedContainers.has(id);
|
|
45
|
+
}
|
|
36
46
|
getInnerTextSecure(el) {
|
|
37
47
|
const id = this.app.nodes.getID(el);
|
|
38
48
|
if (!id) {
|
|
@@ -42,6 +52,7 @@ class Sanitizer {
|
|
|
42
52
|
}
|
|
43
53
|
clear() {
|
|
44
54
|
this.masked.clear();
|
|
55
|
+
this.maskedContainers.clear();
|
|
45
56
|
}
|
|
46
57
|
}
|
|
47
58
|
exports.default = Sanitizer;
|
package/cjs/app/session.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import App from "./index.js";
|
|
2
1
|
interface SessionInfo {
|
|
3
2
|
sessionID: string | null;
|
|
4
3
|
metadata: Record<string, string>;
|
|
@@ -6,20 +5,16 @@ interface SessionInfo {
|
|
|
6
5
|
}
|
|
7
6
|
declare type OnUpdateCallback = (i: Partial<SessionInfo>) => void;
|
|
8
7
|
export default class Session {
|
|
9
|
-
private app;
|
|
10
8
|
private metadata;
|
|
11
9
|
private userID;
|
|
12
10
|
private sessionID;
|
|
13
|
-
private activityState;
|
|
14
11
|
private callbacks;
|
|
15
|
-
constructor(app: App);
|
|
16
12
|
attachUpdateCallback(cb: OnUpdateCallback): void;
|
|
17
13
|
private handleUpdate;
|
|
18
|
-
update(
|
|
19
|
-
private _setMetadata;
|
|
20
|
-
private _setUserID;
|
|
14
|
+
update(newInfo: Partial<SessionInfo>): void;
|
|
21
15
|
setMetadata(key: string, value: string): void;
|
|
22
16
|
setUserID(userID: string): void;
|
|
23
17
|
getInfo(): SessionInfo;
|
|
18
|
+
reset(): void;
|
|
24
19
|
}
|
|
25
20
|
export {};
|
package/cjs/app/session.js
CHANGED
|
@@ -1,61 +1,43 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const messages_js_1 = require("../common/messages.js");
|
|
4
|
-
var ActivityState;
|
|
5
|
-
(function (ActivityState) {
|
|
6
|
-
ActivityState[ActivityState["NotActive"] = 0] = "NotActive";
|
|
7
|
-
ActivityState[ActivityState["Starting"] = 1] = "Starting";
|
|
8
|
-
ActivityState[ActivityState["Active"] = 2] = "Active";
|
|
9
|
-
})(ActivityState || (ActivityState = {}));
|
|
10
3
|
class Session {
|
|
11
|
-
constructor(
|
|
12
|
-
this.app = app;
|
|
4
|
+
constructor() {
|
|
13
5
|
this.metadata = {};
|
|
14
6
|
this.userID = null;
|
|
15
7
|
this.sessionID = null;
|
|
16
|
-
this.activityState = ActivityState.NotActive;
|
|
17
8
|
this.callbacks = [];
|
|
18
9
|
}
|
|
19
10
|
attachUpdateCallback(cb) {
|
|
20
11
|
this.callbacks.push(cb);
|
|
21
12
|
}
|
|
22
|
-
handleUpdate() {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
delete sessInfo.userID;
|
|
13
|
+
handleUpdate(newInfo) {
|
|
14
|
+
if (newInfo.userID == null) {
|
|
15
|
+
delete newInfo.userID;
|
|
26
16
|
}
|
|
27
|
-
if (
|
|
28
|
-
delete
|
|
17
|
+
if (newInfo.sessionID == null) {
|
|
18
|
+
delete newInfo.sessionID;
|
|
29
19
|
}
|
|
30
|
-
this.callbacks.forEach(cb => cb(
|
|
20
|
+
this.callbacks.forEach(cb => cb(newInfo));
|
|
31
21
|
}
|
|
32
|
-
update(
|
|
33
|
-
if (userID
|
|
34
|
-
this.
|
|
22
|
+
update(newInfo) {
|
|
23
|
+
if (newInfo.userID !== undefined) { // TODO clear nullable/undefinable types
|
|
24
|
+
this.userID = newInfo.userID;
|
|
35
25
|
}
|
|
36
|
-
if (metadata !== undefined) {
|
|
37
|
-
Object.entries(metadata).forEach(
|
|
26
|
+
if (newInfo.metadata !== undefined) {
|
|
27
|
+
Object.entries(newInfo.metadata).forEach(([k, v]) => this.metadata[k] = v);
|
|
38
28
|
}
|
|
39
|
-
if (sessionID !== undefined) {
|
|
40
|
-
this.sessionID = sessionID;
|
|
29
|
+
if (newInfo.sessionID !== undefined) {
|
|
30
|
+
this.sessionID = newInfo.sessionID;
|
|
41
31
|
}
|
|
42
|
-
this.handleUpdate();
|
|
43
|
-
}
|
|
44
|
-
_setMetadata(key, value) {
|
|
45
|
-
this.app.send(new messages_js_1.Metadata(key, value));
|
|
46
|
-
this.metadata[key] = value;
|
|
47
|
-
}
|
|
48
|
-
_setUserID(userID) {
|
|
49
|
-
this.app.send(new messages_js_1.UserID(userID));
|
|
50
|
-
this.userID = userID;
|
|
32
|
+
this.handleUpdate(newInfo);
|
|
51
33
|
}
|
|
52
34
|
setMetadata(key, value) {
|
|
53
|
-
this.
|
|
54
|
-
this.handleUpdate();
|
|
35
|
+
this.metadata[key] = value;
|
|
36
|
+
this.handleUpdate({ metadata: { [key]: value } });
|
|
55
37
|
}
|
|
56
38
|
setUserID(userID) {
|
|
57
|
-
this.
|
|
58
|
-
this.handleUpdate();
|
|
39
|
+
this.userID = userID;
|
|
40
|
+
this.handleUpdate({ userID });
|
|
59
41
|
}
|
|
60
42
|
getInfo() {
|
|
61
43
|
return {
|
|
@@ -64,5 +46,10 @@ class Session {
|
|
|
64
46
|
userID: this.userID,
|
|
65
47
|
};
|
|
66
48
|
}
|
|
49
|
+
reset() {
|
|
50
|
+
this.metadata = {};
|
|
51
|
+
this.userID = null;
|
|
52
|
+
this.sessionID = null;
|
|
53
|
+
}
|
|
67
54
|
}
|
|
68
55
|
exports.default = Session;
|
package/cjs/index.js
CHANGED
|
@@ -127,7 +127,7 @@ class API {
|
|
|
127
127
|
// no-cors issue only with text/plain or not-set Content-Type
|
|
128
128
|
// req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
|
129
129
|
req.send(JSON.stringify({
|
|
130
|
-
trackerVersion: '3.5.
|
|
130
|
+
trackerVersion: '3.5.14',
|
|
131
131
|
projectKey: options.projectKey,
|
|
132
132
|
doNotTrack,
|
|
133
133
|
// TODO: add precise reason (an exact API missing)
|
|
@@ -158,7 +158,7 @@ class API {
|
|
|
158
158
|
if (this.app === null) {
|
|
159
159
|
return;
|
|
160
160
|
}
|
|
161
|
-
this.app.stop();
|
|
161
|
+
this.app.stop(true);
|
|
162
162
|
}
|
|
163
163
|
getSessionToken() {
|
|
164
164
|
if (this.app === null) {
|
package/cjs/modules/console.d.ts
CHANGED
package/cjs/modules/console.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const guards_js_1 = require("../app/guards.js");
|
|
3
4
|
const utils_js_1 = require("../utils.js");
|
|
4
5
|
const messages_js_1 = require("../common/messages.js");
|
|
5
6
|
const printError = utils_js_1.IN_BROWSER && 'InstallTrigger' in window // detect Firefox
|
|
@@ -115,7 +116,7 @@ function default_1(app, opts) {
|
|
|
115
116
|
});
|
|
116
117
|
patchConsole(window.console);
|
|
117
118
|
app.nodes.attachNodeCallback(app.safe(node => {
|
|
118
|
-
if (node
|
|
119
|
+
if ((0, guards_js_1.hasTag)(node, "IFRAME")) { // TODO: newContextCallback
|
|
119
120
|
let context = node.contentWindow;
|
|
120
121
|
if (context) {
|
|
121
122
|
patchConsole(context.console);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import App from "../app/index.js";
|
|
1
|
+
import type App from "../app/index.js";
|
|
2
2
|
export default function (app: App | null): void;
|
package/cjs/modules/cssrules.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const messages_js_1 = require("../common/messages.js");
|
|
4
|
+
const guards_js_1 = require("../app/guards.js");
|
|
4
5
|
function default_1(app) {
|
|
5
6
|
if (app === null) {
|
|
6
7
|
return;
|
|
@@ -32,10 +33,7 @@ function default_1(app) {
|
|
|
32
33
|
return deleteRule.call(this, index);
|
|
33
34
|
};
|
|
34
35
|
app.nodes.attachNodeCallback((node) => {
|
|
35
|
-
if (!(node
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
if (!(node.sheet instanceof CSSStyleSheet)) {
|
|
36
|
+
if (!(0, guards_js_1.hasTag)(node, "STYLE") || !node.sheet) {
|
|
39
37
|
return;
|
|
40
38
|
}
|
|
41
39
|
if (node.textContent !== null && node.textContent.trim().length > 0) {
|
package/cjs/modules/img.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import App from "../app/index.js";
|
|
1
|
+
import type App from "../app/index.js";
|
|
2
2
|
export default function (app: App): void;
|
package/cjs/modules/img.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const utils_js_1 = require("../utils.js");
|
|
4
4
|
const messages_js_1 = require("../common/messages.js");
|
|
5
|
+
const guards_js_1 = require("../app/guards.js");
|
|
5
6
|
const PLACEHOLDER_SRC = "https://static.openreplay.com/tracker/placeholder.jpeg";
|
|
6
7
|
function default_1(app) {
|
|
7
8
|
function sendPlaceholder(id, node) {
|
|
@@ -19,7 +20,7 @@ function default_1(app) {
|
|
|
19
20
|
if (id === undefined) {
|
|
20
21
|
return;
|
|
21
22
|
}
|
|
22
|
-
const { src, complete, naturalWidth, naturalHeight } = this;
|
|
23
|
+
const { src, complete, naturalWidth, naturalHeight, srcset } = this;
|
|
23
24
|
if (!complete) {
|
|
24
25
|
return;
|
|
25
26
|
}
|
|
@@ -33,29 +34,36 @@ function default_1(app) {
|
|
|
33
34
|
}
|
|
34
35
|
else {
|
|
35
36
|
app.send(new messages_js_1.SetNodeAttributeURLBased(id, 'src', src, app.getBaseHref()));
|
|
37
|
+
srcset && app.send(new messages_js_1.SetNodeAttribute(id, 'srcset', srcset));
|
|
36
38
|
}
|
|
37
39
|
});
|
|
38
40
|
const observer = new MutationObserver((mutations) => {
|
|
39
41
|
for (const mutation of mutations) {
|
|
40
|
-
if (mutation.type === "attributes"
|
|
42
|
+
if (mutation.type === "attributes") {
|
|
41
43
|
const target = mutation.target;
|
|
42
44
|
const id = app.nodes.getID(target);
|
|
43
45
|
if (id === undefined) {
|
|
44
46
|
return;
|
|
45
47
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
if (mutation.attributeName === "src") {
|
|
49
|
+
const src = target.src;
|
|
50
|
+
app.send(new messages_js_1.SetNodeAttributeURLBased(id, 'src', src, app.getBaseHref()));
|
|
51
|
+
}
|
|
52
|
+
if (mutation.attributeName === "srcset") {
|
|
53
|
+
const srcset = target.srcset;
|
|
54
|
+
app.send(new messages_js_1.SetNodeAttribute(id, 'srcset', srcset));
|
|
55
|
+
}
|
|
48
56
|
}
|
|
49
57
|
}
|
|
50
58
|
});
|
|
51
59
|
app.nodes.attachNodeCallback((node) => {
|
|
52
|
-
if (!(node
|
|
60
|
+
if (!(0, guards_js_1.hasTag)(node, "IMG")) {
|
|
53
61
|
return;
|
|
54
62
|
}
|
|
55
63
|
app.nodes.attachElementListener('error', node, sendImgSrc);
|
|
56
64
|
app.nodes.attachElementListener('load', node, sendImgSrc);
|
|
57
65
|
sendImgSrc.call(node);
|
|
58
|
-
observer.observe(node, { attributes: true });
|
|
66
|
+
observer.observe(node, { attributes: true, attributeFilter: ["src", "srcset"] });
|
|
59
67
|
});
|
|
60
68
|
}
|
|
61
69
|
exports.default = default_1;
|
package/cjs/modules/input.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import App from "../app/index.js";
|
|
1
|
+
import type App from "../app/index.js";
|
|
2
2
|
declare type TextEditableElement = HTMLInputElement | HTMLTextAreaElement;
|
|
3
3
|
export declare function getInputLabel(node: TextEditableElement): string;
|
|
4
4
|
export declare const enum InputMode {
|
|
@@ -10,6 +10,7 @@ export interface Options {
|
|
|
10
10
|
obscureInputNumbers: boolean;
|
|
11
11
|
obscureInputEmails: boolean;
|
|
12
12
|
defaultInputMode: InputMode;
|
|
13
|
+
obscureInputDates: boolean;
|
|
13
14
|
}
|
|
14
15
|
export default function (app: App, opts: Partial<Options>): void;
|
|
15
16
|
export {};
|