@openreplay/tracker 5.0.1-beta.3 → 5.0.2-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/package.json +1 -1
  3. package/cjs/app/guards.d.ts +0 -20
  4. package/cjs/app/guards.js +0 -33
  5. package/cjs/app/index.d.ts +0 -121
  6. package/cjs/app/index.js +0 -439
  7. package/cjs/app/logger.d.ts +0 -26
  8. package/cjs/app/logger.js +0 -45
  9. package/cjs/app/messages.gen.d.ts +0 -63
  10. package/cjs/app/messages.gen.js +0 -551
  11. package/cjs/app/nodes.d.ts +0 -18
  12. package/cjs/app/nodes.js +0 -82
  13. package/cjs/app/observer/iframe_observer.d.ts +0 -4
  14. package/cjs/app/observer/iframe_observer.js +0 -23
  15. package/cjs/app/observer/iframe_offsets.d.ts +0 -8
  16. package/cjs/app/observer/iframe_offsets.js +0 -59
  17. package/cjs/app/observer/observer.d.ts +0 -23
  18. package/cjs/app/observer/observer.js +0 -337
  19. package/cjs/app/observer/shadow_root_observer.d.ts +0 -4
  20. package/cjs/app/observer/shadow_root_observer.js +0 -21
  21. package/cjs/app/observer/top_observer.d.ts +0 -24
  22. package/cjs/app/observer/top_observer.js +0 -115
  23. package/cjs/app/sanitizer.d.ts +0 -24
  24. package/cjs/app/sanitizer.js +0 -76
  25. package/cjs/app/session.d.ts +0 -38
  26. package/cjs/app/session.js +0 -114
  27. package/cjs/app/ticker.d.ts +0 -12
  28. package/cjs/app/ticker.js +0 -42
  29. package/cjs/common/interaction.d.ts +0 -24
  30. package/cjs/common/interaction.js +0 -2
  31. package/cjs/common/messages.gen.d.ts +0 -427
  32. package/cjs/common/messages.gen.js +0 -4
  33. package/cjs/index.d.ts +0 -47
  34. package/cjs/index.js +0 -254
  35. package/cjs/modules/connection.d.ts +0 -2
  36. package/cjs/modules/connection.js +0 -15
  37. package/cjs/modules/console.d.ts +0 -6
  38. package/cjs/modules/console.js +0 -119
  39. package/cjs/modules/constructedStyleSheets.d.ts +0 -4
  40. package/cjs/modules/constructedStyleSheets.js +0 -131
  41. package/cjs/modules/cssrules.d.ts +0 -2
  42. package/cjs/modules/cssrules.js +0 -99
  43. package/cjs/modules/exception.d.ts +0 -16
  44. package/cjs/modules/exception.js +0 -77
  45. package/cjs/modules/focus.d.ts +0 -2
  46. package/cjs/modules/focus.js +0 -45
  47. package/cjs/modules/fonts.d.ts +0 -2
  48. package/cjs/modules/fonts.js +0 -57
  49. package/cjs/modules/img.d.ts +0 -2
  50. package/cjs/modules/img.js +0 -110
  51. package/cjs/modules/input.d.ts +0 -16
  52. package/cjs/modules/input.js +0 -163
  53. package/cjs/modules/mouse.d.ts +0 -2
  54. package/cjs/modules/mouse.js +0 -148
  55. package/cjs/modules/network.d.ts +0 -28
  56. package/cjs/modules/network.js +0 -237
  57. package/cjs/modules/performance.d.ts +0 -7
  58. package/cjs/modules/performance.js +0 -53
  59. package/cjs/modules/scroll.d.ts +0 -2
  60. package/cjs/modules/scroll.js +0 -79
  61. package/cjs/modules/timing.d.ts +0 -7
  62. package/cjs/modules/timing.js +0 -160
  63. package/cjs/modules/viewport.d.ts +0 -2
  64. package/cjs/modules/viewport.js +0 -43
  65. package/cjs/package.json +0 -1
  66. package/cjs/utils.d.ts +0 -13
  67. package/cjs/utils.js +0 -71
  68. package/cjs/vendors/finder/finder.d.ts +0 -12
  69. package/cjs/vendors/finder/finder.js +0 -352
  70. package/lib/app/guards.d.ts +0 -20
  71. package/lib/app/guards.js +0 -23
  72. package/lib/app/index.d.ts +0 -121
  73. package/lib/app/index.js +0 -435
  74. package/lib/app/logger.d.ts +0 -26
  75. package/lib/app/logger.js +0 -41
  76. package/lib/app/messages.gen.d.ts +0 -63
  77. package/lib/app/messages.gen.js +0 -486
  78. package/lib/app/nodes.d.ts +0 -18
  79. package/lib/app/nodes.js +0 -79
  80. package/lib/app/observer/iframe_observer.d.ts +0 -4
  81. package/lib/app/observer/iframe_observer.js +0 -20
  82. package/lib/app/observer/iframe_offsets.d.ts +0 -8
  83. package/lib/app/observer/iframe_offsets.js +0 -56
  84. package/lib/app/observer/observer.d.ts +0 -23
  85. package/lib/app/observer/observer.js +0 -334
  86. package/lib/app/observer/shadow_root_observer.d.ts +0 -4
  87. package/lib/app/observer/shadow_root_observer.js +0 -18
  88. package/lib/app/observer/top_observer.d.ts +0 -24
  89. package/lib/app/observer/top_observer.js +0 -112
  90. package/lib/app/sanitizer.d.ts +0 -24
  91. package/lib/app/sanitizer.js +0 -72
  92. package/lib/app/session.d.ts +0 -38
  93. package/lib/app/session.js +0 -111
  94. package/lib/app/ticker.d.ts +0 -12
  95. package/lib/app/ticker.js +0 -39
  96. package/lib/common/interaction.d.ts +0 -24
  97. package/lib/common/interaction.js +0 -1
  98. package/lib/common/messages.gen.d.ts +0 -427
  99. package/lib/common/messages.gen.js +0 -3
  100. package/lib/common/tsconfig.tsbuildinfo +0 -1
  101. package/lib/index.d.ts +0 -47
  102. package/lib/index.js +0 -248
  103. package/lib/modules/connection.d.ts +0 -2
  104. package/lib/modules/connection.js +0 -12
  105. package/lib/modules/console.d.ts +0 -6
  106. package/lib/modules/console.js +0 -116
  107. package/lib/modules/constructedStyleSheets.d.ts +0 -4
  108. package/lib/modules/constructedStyleSheets.js +0 -126
  109. package/lib/modules/cssrules.d.ts +0 -2
  110. package/lib/modules/cssrules.js +0 -97
  111. package/lib/modules/exception.d.ts +0 -16
  112. package/lib/modules/exception.js +0 -71
  113. package/lib/modules/focus.d.ts +0 -2
  114. package/lib/modules/focus.js +0 -42
  115. package/lib/modules/fonts.d.ts +0 -2
  116. package/lib/modules/fonts.js +0 -54
  117. package/lib/modules/img.d.ts +0 -2
  118. package/lib/modules/img.js +0 -107
  119. package/lib/modules/input.d.ts +0 -16
  120. package/lib/modules/input.js +0 -158
  121. package/lib/modules/mouse.d.ts +0 -2
  122. package/lib/modules/mouse.js +0 -145
  123. package/lib/modules/network.d.ts +0 -28
  124. package/lib/modules/network.js +0 -234
  125. package/lib/modules/performance.d.ts +0 -7
  126. package/lib/modules/performance.js +0 -49
  127. package/lib/modules/scroll.d.ts +0 -2
  128. package/lib/modules/scroll.js +0 -76
  129. package/lib/modules/timing.d.ts +0 -7
  130. package/lib/modules/timing.js +0 -157
  131. package/lib/modules/viewport.d.ts +0 -2
  132. package/lib/modules/viewport.js +0 -40
  133. package/lib/utils.d.ts +0 -13
  134. package/lib/utils.js +0 -61
  135. package/lib/vendors/finder/finder.d.ts +0 -12
  136. package/lib/vendors/finder/finder.js +0 -348
package/cjs/app/nodes.js DELETED
@@ -1,82 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- class Nodes {
4
- constructor(node_id) {
5
- this.node_id = node_id;
6
- this.nodes = [];
7
- this.nodeCallbacks = [];
8
- this.elementListeners = new Map();
9
- }
10
- // Attached once per Tracker instance
11
- attachNodeCallback(nodeCallback) {
12
- this.nodeCallbacks.push(nodeCallback);
13
- }
14
- attachNodeListener(node, type, listener, useCapture = true) {
15
- const id = this.getID(node);
16
- if (id === undefined) {
17
- return;
18
- }
19
- node.addEventListener(type, listener, useCapture);
20
- let listeners = this.elementListeners.get(id);
21
- if (listeners === undefined) {
22
- listeners = [];
23
- this.elementListeners.set(id, listeners);
24
- }
25
- listeners.push([type, listener, useCapture]);
26
- }
27
- registerNode(node) {
28
- let id = node[this.node_id];
29
- const isNew = id === undefined;
30
- if (isNew) {
31
- id = this.nodes.length;
32
- this.nodes[id] = node;
33
- node[this.node_id] = id;
34
- }
35
- return [id, isNew];
36
- }
37
- unregisterNode(node) {
38
- const id = node[this.node_id];
39
- if (id !== undefined) {
40
- delete node[this.node_id];
41
- delete this.nodes[id];
42
- const listeners = this.elementListeners.get(id);
43
- if (listeners !== undefined) {
44
- this.elementListeners.delete(id);
45
- listeners.forEach((listener) => node.removeEventListener(listener[0], listener[1], listener[2]));
46
- }
47
- }
48
- return id;
49
- }
50
- cleanTree() {
51
- // sadly we keep empty items in array here resulting in some memory still being used
52
- // but its still better than keeping dead nodes or undef elements
53
- // plus we keep our index positions for new/alive nodes
54
- // performance test: 3ms for 30k nodes with 17k dead ones
55
- for (let i = 0; i < this.nodes.length; i++) {
56
- const node = this.nodes[i];
57
- if (node && !document.contains(node)) {
58
- this.unregisterNode(node);
59
- }
60
- }
61
- }
62
- callNodeCallbacks(node, isStart) {
63
- this.nodeCallbacks.forEach((cb) => cb(node, isStart));
64
- }
65
- getID(node) {
66
- return node[this.node_id];
67
- }
68
- getNode(id) {
69
- return this.nodes[id];
70
- }
71
- clear() {
72
- for (let id = 0; id < this.nodes.length; id++) {
73
- const node = this.nodes[id];
74
- if (node === undefined) {
75
- continue;
76
- }
77
- this.unregisterNode(node);
78
- }
79
- this.nodes.length = 0;
80
- }
81
- }
82
- exports.default = Nodes;
@@ -1,4 +0,0 @@
1
- import Observer from './observer.js';
2
- export default class IFrameObserver extends Observer {
3
- observe(iframe: HTMLIFrameElement): void;
4
- }
@@ -1,23 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const observer_js_1 = require("./observer.js");
4
- const messages_gen_js_1 = require("../messages.gen.js");
5
- class IFrameObserver extends observer_js_1.default {
6
- observe(iframe) {
7
- const doc = iframe.contentDocument;
8
- const hostID = this.app.nodes.getID(iframe);
9
- if (!doc || hostID === undefined) {
10
- return;
11
- } //log TODO common app.logger
12
- // Have to observe document, because the inner <html> might be changed
13
- this.observeRoot(doc, (docID) => {
14
- //MBTODO: do not send if empty (send on load? it might be in-place iframe, like our replayer, which does not get loaded)
15
- if (docID === undefined) {
16
- console.log('OpenReplay: Iframe document not bound');
17
- return;
18
- }
19
- this.app.send((0, messages_gen_js_1.CreateIFrameDocument)(hostID, docID));
20
- });
21
- }
22
- }
23
- exports.default = IFrameObserver;
@@ -1,8 +0,0 @@
1
- export type Offset = [/*left:*/ number, /*top: */ number];
2
- export default class IFrameOffsets {
3
- private readonly states;
4
- private calcOffset;
5
- getDocumentOffset(doc: Document): Offset;
6
- observe(iFrame: HTMLIFrameElement): void;
7
- clear(): void;
8
- }
@@ -1,59 +0,0 @@
1
- "use strict";
2
- // Le truc - for defining an absolute offset for (nested) iframe documents. (To track mouse movments)
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- class IFrameOffsets {
5
- constructor() {
6
- this.states = new Map();
7
- }
8
- calcOffset(state) {
9
- let parLeft = 0, parTop = 0;
10
- if (state.parent) {
11
- ;
12
- [parLeft, parTop] = this.calcOffset(state.parent);
13
- }
14
- if (!state.offset) {
15
- const { left, top } = state.iFrame.getBoundingClientRect();
16
- state.offset = [left, top];
17
- }
18
- const [left, top] = state.offset;
19
- return [parLeft + left, parTop + top]; // TODO: store absolute sum, invalidate whole subtree. Otherwise it is summated on each mousemove
20
- }
21
- getDocumentOffset(doc) {
22
- const state = this.states.get(doc);
23
- if (!state) {
24
- return [0, 0];
25
- } // topmost doc
26
- return this.calcOffset(state);
27
- }
28
- observe(iFrame) {
29
- var _a;
30
- const doc = iFrame.contentDocument;
31
- if (!doc) {
32
- return;
33
- }
34
- const parentDoc = iFrame.ownerDocument;
35
- const parentState = this.states.get(parentDoc);
36
- const state = {
37
- offset: null,
38
- iFrame,
39
- parent: parentState || null,
40
- clear: () => {
41
- var _a;
42
- parentDoc.removeEventListener('scroll', invalidateOffset);
43
- (_a = parentDoc.defaultView) === null || _a === void 0 ? void 0 : _a.removeEventListener('resize', invalidateOffset);
44
- },
45
- };
46
- const invalidateOffset = () => {
47
- state.offset = null;
48
- };
49
- // anything more reliable? This does not cover all cases (layout changes are ignored, for ex.)
50
- parentDoc.addEventListener('scroll', invalidateOffset);
51
- (_a = parentDoc.defaultView) === null || _a === void 0 ? void 0 : _a.addEventListener('resize', invalidateOffset);
52
- this.states.set(doc, state);
53
- }
54
- clear() {
55
- this.states.forEach((s) => s.clear());
56
- this.states.clear();
57
- }
58
- }
59
- exports.default = IFrameOffsets;
@@ -1,23 +0,0 @@
1
- import App from '../index.js';
2
- export default abstract class Observer {
3
- protected readonly app: App;
4
- protected readonly isTopContext: boolean;
5
- private readonly observer;
6
- private readonly commited;
7
- private readonly recents;
8
- private readonly indexes;
9
- private readonly attributesMap;
10
- private readonly textSet;
11
- constructor(app: App, isTopContext?: boolean);
12
- private clear;
13
- private sendNodeAttribute;
14
- private sendNodeData;
15
- private bindNode;
16
- private bindTree;
17
- private unbindTree;
18
- private _commitNode;
19
- private commitNode;
20
- private commitNodes;
21
- protected observeRoot(node: Node, beforeCommit: (id?: number) => unknown, nodeToBind?: Node): void;
22
- disconnect(): void;
23
- }
@@ -1,337 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const messages_gen_js_1 = require("../messages.gen.js");
4
- const guards_js_1 = require("../guards.js");
5
- function isIgnored(node) {
6
- if ((0, guards_js_1.isTextNode)(node)) {
7
- return false;
8
- }
9
- if (!(0, guards_js_1.isElementNode)(node)) {
10
- return true;
11
- }
12
- const tag = node.tagName.toUpperCase();
13
- if (tag === 'LINK') {
14
- const rel = node.getAttribute('rel');
15
- const as = node.getAttribute('as');
16
- return !((rel === null || rel === void 0 ? void 0 : rel.includes('stylesheet')) || as === 'style' || as === 'font');
17
- }
18
- return (tag === 'SCRIPT' || tag === 'NOSCRIPT' || tag === 'META' || tag === 'TITLE' || tag === 'BASE');
19
- }
20
- function isObservable(node) {
21
- if ((0, guards_js_1.isRootNode)(node)) {
22
- return true;
23
- }
24
- return !isIgnored(node);
25
- }
26
- /*
27
- TODO:
28
- - fix unbinding logic + send all removals first (ensure sequence is correct)
29
- - use document as a 0-node in the upper context (should be updated in player at first)
30
- */
31
- var RecentsType;
32
- (function (RecentsType) {
33
- RecentsType[RecentsType["New"] = 0] = "New";
34
- RecentsType[RecentsType["Removed"] = 1] = "Removed";
35
- RecentsType[RecentsType["Changed"] = 2] = "Changed";
36
- })(RecentsType || (RecentsType = {}));
37
- class Observer {
38
- constructor(app, isTopContext = false) {
39
- this.app = app;
40
- this.isTopContext = isTopContext;
41
- this.commited = [];
42
- this.recents = new Map();
43
- this.indexes = [];
44
- this.attributesMap = new Map();
45
- this.textSet = new Set();
46
- this.observer = new MutationObserver(this.app.safe((mutations) => {
47
- for (const mutation of mutations) {
48
- // mutations order is sequential
49
- const target = mutation.target;
50
- const type = mutation.type;
51
- if (!isObservable(target)) {
52
- continue;
53
- }
54
- if (type === 'childList') {
55
- for (let i = 0; i < mutation.removedNodes.length; i++) {
56
- // Should be the same as bindTree(mutation.removedNodes[i]), but logic needs to be be untied
57
- if (isObservable(mutation.removedNodes[i])) {
58
- this.bindNode(mutation.removedNodes[i]);
59
- }
60
- }
61
- for (let i = 0; i < mutation.addedNodes.length; i++) {
62
- this.bindTree(mutation.addedNodes[i]);
63
- }
64
- continue;
65
- }
66
- const id = this.app.nodes.getID(target);
67
- if (id === undefined) {
68
- continue;
69
- }
70
- if (!this.recents.has(id)) {
71
- this.recents.set(id, RecentsType.Changed); // TODO only when altered
72
- }
73
- if (type === 'attributes') {
74
- const name = mutation.attributeName;
75
- if (name === null) {
76
- continue;
77
- }
78
- let attr = this.attributesMap.get(id);
79
- if (attr === undefined) {
80
- this.attributesMap.set(id, (attr = new Set()));
81
- }
82
- attr.add(name);
83
- continue;
84
- }
85
- if (type === 'characterData') {
86
- this.textSet.add(id);
87
- continue;
88
- }
89
- }
90
- this.commitNodes();
91
- }));
92
- }
93
- clear() {
94
- this.commited.length = 0;
95
- this.recents.clear();
96
- this.indexes.length = 1;
97
- this.attributesMap.clear();
98
- this.textSet.clear();
99
- }
100
- sendNodeAttribute(id, node, name, value) {
101
- if ((0, guards_js_1.isSVGElement)(node)) {
102
- if (name.substr(0, 6) === 'xlink:') {
103
- name = name.substr(6);
104
- }
105
- if (value === null) {
106
- this.app.send((0, messages_gen_js_1.RemoveNodeAttribute)(id, name));
107
- }
108
- else if (name === 'href') {
109
- if (value.length > 1e5) {
110
- value = '';
111
- }
112
- this.app.send((0, messages_gen_js_1.SetNodeAttributeURLBased)(id, name, value, this.app.getBaseHref()));
113
- }
114
- else {
115
- this.app.send((0, messages_gen_js_1.SetNodeAttribute)(id, name, value));
116
- }
117
- return;
118
- }
119
- if (name === 'src' ||
120
- name === 'srcset' ||
121
- name === 'integrity' ||
122
- name === 'crossorigin' ||
123
- name === 'autocomplete' ||
124
- name.substr(0, 2) === 'on') {
125
- return;
126
- }
127
- if (name === 'value' &&
128
- (0, guards_js_1.hasTag)(node, 'input') &&
129
- node.type !== 'button' &&
130
- node.type !== 'reset' &&
131
- node.type !== 'submit') {
132
- return;
133
- }
134
- if (value === null) {
135
- this.app.send((0, messages_gen_js_1.RemoveNodeAttribute)(id, name));
136
- return;
137
- }
138
- if (name === 'style' || (name === 'href' && (0, guards_js_1.hasTag)(node, 'link'))) {
139
- this.app.send((0, messages_gen_js_1.SetNodeAttributeURLBased)(id, name, value, this.app.getBaseHref()));
140
- return;
141
- }
142
- if (name === 'href' || value.length > 1e5) {
143
- value = '';
144
- }
145
- this.app.send((0, messages_gen_js_1.SetNodeAttribute)(id, name, value));
146
- }
147
- sendNodeData(id, parentElement, data) {
148
- if ((0, guards_js_1.hasTag)(parentElement, 'style')) {
149
- this.app.send((0, messages_gen_js_1.SetCSSDataURLBased)(id, data, this.app.getBaseHref()));
150
- return;
151
- }
152
- data = this.app.sanitizer.sanitize(id, data);
153
- this.app.send((0, messages_gen_js_1.SetNodeData)(id, data));
154
- }
155
- bindNode(node) {
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.get(id) !== RecentsType.New) {
161
- this.recents.set(id, RecentsType.Removed);
162
- }
163
- }
164
- bindTree(node) {
165
- if (!isObservable(node)) {
166
- return;
167
- }
168
- this.bindNode(node);
169
- const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_TEXT, {
170
- acceptNode: (node) => isIgnored(node) || this.app.nodes.getID(node) !== undefined
171
- ? NodeFilter.FILTER_REJECT
172
- : NodeFilter.FILTER_ACCEPT,
173
- },
174
- // @ts-ignore
175
- false);
176
- while (walker.nextNode()) {
177
- this.bindNode(walker.currentNode);
178
- }
179
- }
180
- unbindTree(node) {
181
- const id = this.app.nodes.unregisterNode(node);
182
- if (id !== undefined && this.recents.get(id) === RecentsType.Removed) {
183
- // Sending RemoveNode only for parent to maintain
184
- this.app.send((0, messages_gen_js_1.RemoveNode)(id));
185
- // Unregistering all the children in order to clear the memory
186
- const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_TEXT, {
187
- acceptNode: (node) => isIgnored(node) || this.app.nodes.getID(node) === undefined
188
- ? NodeFilter.FILTER_REJECT
189
- : NodeFilter.FILTER_ACCEPT,
190
- },
191
- // @ts-ignore
192
- false);
193
- while (walker.nextNode()) {
194
- this.app.nodes.unregisterNode(walker.currentNode);
195
- }
196
- // MBTODO: count and send RemovedNodesCount (for the page crash detection in heuristics)
197
- }
198
- }
199
- // A top-consumption function on the infinite lists test. (~1% of performance resources)
200
- _commitNode(id, node) {
201
- if ((0, guards_js_1.isRootNode)(node)) {
202
- return true;
203
- }
204
- const parent = node.parentNode;
205
- let parentID;
206
- // Disable parent check for the upper context HTMLHtmlElement, because it is root there... (before)
207
- // TODO: get rid of "special" cases (there is an issue with CreateDocument altered behaviour though)
208
- // TODO: Clean the logic (though now it workd fine)
209
- if (!(0, guards_js_1.hasTag)(node, 'html') || !this.isTopContext) {
210
- if (parent === null) {
211
- // Sometimes one observation contains attribute mutations for the removimg node, which gets ignored here.
212
- // That shouldn't affect the visual rendering ( should it? maybe when transition applied? )
213
- this.unbindTree(node);
214
- return false;
215
- }
216
- parentID = this.app.nodes.getID(parent);
217
- if (parentID === undefined) {
218
- this.unbindTree(node);
219
- return false;
220
- }
221
- if (!this.commitNode(parentID)) {
222
- this.unbindTree(node);
223
- return false;
224
- }
225
- this.app.sanitizer.handleNode(id, parentID, node);
226
- if (this.app.sanitizer.isHidden(parentID)) {
227
- return false;
228
- }
229
- }
230
- // From here parentID === undefined if node is top context HTML node
231
- let sibling = node.previousSibling;
232
- while (sibling !== null) {
233
- const siblingID = this.app.nodes.getID(sibling);
234
- if (siblingID !== undefined) {
235
- this.commitNode(siblingID);
236
- this.indexes[id] = this.indexes[siblingID] + 1;
237
- break;
238
- }
239
- sibling = sibling.previousSibling;
240
- }
241
- if (sibling === null) {
242
- this.indexes[id] = 0;
243
- }
244
- const recentsType = this.recents.get(id);
245
- const isNew = recentsType === RecentsType.New;
246
- const index = this.indexes[id];
247
- if (index === undefined) {
248
- throw 'commitNode: missing node index';
249
- }
250
- if (isNew) {
251
- if ((0, guards_js_1.isElementNode)(node)) {
252
- let el = node;
253
- if (parentID !== undefined) {
254
- if (this.app.sanitizer.isHidden(id)) {
255
- const width = el.clientWidth;
256
- const height = el.clientHeight;
257
- el = node.cloneNode();
258
- el.style.width = `${width}px`;
259
- el.style.height = `${height}px`;
260
- }
261
- this.app.send((0, messages_gen_js_1.CreateElementNode)(id, parentID, index, el.tagName, (0, guards_js_1.isSVGElement)(node)));
262
- }
263
- for (let i = 0; i < el.attributes.length; i++) {
264
- const attr = el.attributes[i];
265
- this.sendNodeAttribute(id, el, attr.nodeName, attr.value);
266
- }
267
- }
268
- else if ((0, guards_js_1.isTextNode)(node)) {
269
- // for text node id != 0, hence parentID !== undefined and parent is Element
270
- this.app.send((0, messages_gen_js_1.CreateTextNode)(id, parentID, index));
271
- this.sendNodeData(id, parent, node.data);
272
- }
273
- return true;
274
- }
275
- if (recentsType === RecentsType.Removed && parentID !== undefined) {
276
- this.app.send((0, messages_gen_js_1.MoveNode)(id, parentID, index));
277
- }
278
- const attr = this.attributesMap.get(id);
279
- if (attr !== undefined) {
280
- if (!(0, guards_js_1.isElementNode)(node)) {
281
- throw 'commitNode: node is not an element';
282
- }
283
- for (const name of attr) {
284
- this.sendNodeAttribute(id, node, name, node.getAttribute(name));
285
- }
286
- }
287
- if (this.textSet.has(id)) {
288
- if (!(0, guards_js_1.isTextNode)(node)) {
289
- throw 'commitNode: node is not a text';
290
- }
291
- // for text node id != 0, hence parent is Element
292
- this.sendNodeData(id, parent, node.data);
293
- }
294
- return true;
295
- }
296
- commitNode(id) {
297
- const node = this.app.nodes.getNode(id);
298
- if (node === undefined) {
299
- return false;
300
- }
301
- const cmt = this.commited[id];
302
- if (cmt !== undefined) {
303
- return cmt;
304
- }
305
- return (this.commited[id] = this._commitNode(id, node));
306
- }
307
- commitNodes(isStart = false) {
308
- let node;
309
- this.recents.forEach((type, id) => {
310
- this.commitNode(id);
311
- if (type === RecentsType.New && (node = this.app.nodes.getNode(id))) {
312
- this.app.nodes.callNodeCallbacks(node, isStart);
313
- }
314
- });
315
- this.clear();
316
- }
317
- // ISSSUE (nodeToBinde should be the same as node in all cases. Look at the comment about 0-node at the beginning of the file.)
318
- // TODO: use one observer instance for all iframes/shadowRoots (composition instiad of inheritance)
319
- observeRoot(node, beforeCommit, nodeToBind = node) {
320
- this.observer.observe(node, {
321
- childList: true,
322
- attributes: true,
323
- characterData: true,
324
- subtree: true,
325
- attributeOldValue: false,
326
- characterDataOldValue: false,
327
- });
328
- this.bindTree(nodeToBind);
329
- beforeCommit(this.app.nodes.getID(node));
330
- this.commitNodes(true);
331
- }
332
- disconnect() {
333
- this.observer.disconnect();
334
- this.clear();
335
- }
336
- }
337
- exports.default = Observer;
@@ -1,4 +0,0 @@
1
- import Observer from './observer.js';
2
- export default class ShadowRootObserver extends Observer {
3
- observe(el: Element): void;
4
- }
@@ -1,21 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const observer_js_1 = require("./observer.js");
4
- const messages_gen_js_1 = require("../messages.gen.js");
5
- class ShadowRootObserver extends observer_js_1.default {
6
- observe(el) {
7
- const shRoot = el.shadowRoot;
8
- const hostID = this.app.nodes.getID(el);
9
- if (!shRoot || hostID === undefined) {
10
- return;
11
- } // log
12
- this.observeRoot(shRoot, (rootID) => {
13
- if (rootID === undefined) {
14
- console.log('OpenReplay: Shadow Root was not bound');
15
- return;
16
- }
17
- this.app.send((0, messages_gen_js_1.CreateIFrameDocument)(hostID, rootID));
18
- });
19
- }
20
- }
21
- exports.default = ShadowRootObserver;
@@ -1,24 +0,0 @@
1
- import Observer from './observer.js';
2
- import { Offset } from './iframe_offsets.js';
3
- import App from '../index.js';
4
- export interface Options {
5
- captureIFrames: boolean;
6
- }
7
- type Context = Window & typeof globalThis;
8
- type ContextCallback = (context: Context) => void;
9
- export default class TopObserver extends Observer {
10
- private readonly options;
11
- private readonly iframeOffsets;
12
- constructor(app: App, options: Partial<Options>);
13
- private readonly contextCallbacks;
14
- private readonly contextsSet;
15
- attachContextCallback(cb: ContextCallback): void;
16
- getDocumentOffset(doc: Document): Offset;
17
- private iframeObservers;
18
- private handleIframe;
19
- private shadowRootObservers;
20
- private handleShadowRoot;
21
- observe(): void;
22
- disconnect(): void;
23
- }
24
- export {};