@openreplay/tracker 3.4.7 → 3.4.11

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 (94) hide show
  1. package/cjs/app/index.d.ts +7 -7
  2. package/cjs/app/index.js +20 -20
  3. package/cjs/app/logger.d.ts +0 -0
  4. package/cjs/app/logger.js +1 -0
  5. package/cjs/app/observer.d.ts +1 -1
  6. package/cjs/app/observer.js +24 -20
  7. package/cjs/app/sanitizer.d.ts +0 -0
  8. package/cjs/app/sanitizer.js +1 -0
  9. package/cjs/app/ticker.d.ts +1 -1
  10. package/cjs/index.d.ts +11 -10
  11. package/cjs/index.js +59 -56
  12. package/cjs/messages/index.d.ts +2 -2
  13. package/cjs/messages/message.d.ts +1 -1
  14. package/cjs/modules/connection.d.ts +1 -1
  15. package/cjs/modules/connection.js +2 -2
  16. package/cjs/modules/console.d.ts +1 -1
  17. package/cjs/modules/console.js +4 -4
  18. package/cjs/modules/cssrules.d.ts +1 -1
  19. package/cjs/modules/cssrules.js +4 -4
  20. package/cjs/modules/exception.d.ts +2 -2
  21. package/cjs/modules/exception.js +4 -4
  22. package/cjs/modules/img.d.ts +1 -1
  23. package/cjs/modules/img.js +6 -6
  24. package/cjs/modules/input.d.ts +1 -1
  25. package/cjs/modules/input.js +11 -11
  26. package/cjs/modules/longtasks.d.ts +1 -1
  27. package/cjs/modules/longtasks.js +2 -2
  28. package/cjs/modules/mouse.d.ts +1 -1
  29. package/cjs/modules/mouse.js +10 -10
  30. package/cjs/modules/performance.d.ts +1 -1
  31. package/cjs/modules/performance.js +5 -5
  32. package/cjs/modules/scroll.d.ts +1 -1
  33. package/cjs/modules/scroll.js +3 -3
  34. package/cjs/modules/timing.d.ts +1 -1
  35. package/cjs/modules/timing.js +6 -6
  36. package/cjs/modules/viewport.d.ts +1 -1
  37. package/cjs/modules/viewport.js +4 -4
  38. package/cjs/utils.js +1 -1
  39. package/lib/app/index.d.ts +7 -7
  40. package/lib/app/index.js +8 -8
  41. package/lib/app/logger.d.ts +0 -0
  42. package/lib/app/logger.js +1 -0
  43. package/lib/app/observer.d.ts +1 -1
  44. package/lib/app/observer.js +7 -3
  45. package/lib/app/sanitizer.d.ts +0 -0
  46. package/lib/app/sanitizer.js +1 -0
  47. package/lib/app/ticker.d.ts +1 -1
  48. package/lib/index.d.ts +11 -10
  49. package/lib/index.js +25 -22
  50. package/lib/messages/index.d.ts +2 -2
  51. package/lib/messages/message.d.ts +1 -1
  52. package/lib/messages/tsconfig.tsbuildinfo +1 -1
  53. package/lib/modules/connection.d.ts +1 -1
  54. package/lib/modules/connection.js +1 -1
  55. package/lib/modules/console.d.ts +1 -1
  56. package/lib/modules/console.js +2 -2
  57. package/lib/modules/cssrules.d.ts +1 -1
  58. package/lib/modules/cssrules.js +1 -1
  59. package/lib/modules/exception.d.ts +2 -2
  60. package/lib/modules/exception.js +1 -1
  61. package/lib/modules/img.d.ts +1 -1
  62. package/lib/modules/img.js +2 -2
  63. package/lib/modules/input.d.ts +1 -1
  64. package/lib/modules/input.js +2 -2
  65. package/lib/modules/longtasks.d.ts +1 -1
  66. package/lib/modules/longtasks.js +1 -1
  67. package/lib/modules/mouse.d.ts +1 -1
  68. package/lib/modules/mouse.js +3 -3
  69. package/lib/modules/performance.d.ts +1 -1
  70. package/lib/modules/performance.js +2 -2
  71. package/lib/modules/scroll.d.ts +1 -1
  72. package/lib/modules/scroll.js +1 -1
  73. package/lib/modules/timing.d.ts +1 -1
  74. package/lib/modules/timing.js +2 -2
  75. package/lib/modules/viewport.d.ts +1 -1
  76. package/lib/modules/viewport.js +1 -1
  77. package/package.json +2 -2
  78. package/tsconfig-base.json +1 -1
  79. package/cjs/app/observer/iframe_observer.d.ts +0 -4
  80. package/cjs/app/observer/iframe_observer.js +0 -21
  81. package/cjs/app/observer/observer.d.ts +0 -46
  82. package/cjs/app/observer/observer.js +0 -353
  83. package/cjs/app/observer/shadow_root_observer.d.ts +0 -4
  84. package/cjs/app/observer/shadow_root_observer.js +0 -21
  85. package/cjs/app/observer/top_observer.d.ts +0 -15
  86. package/cjs/app/observer/top_observer.js +0 -78
  87. package/lib/app/observer/iframe_observer.d.ts +0 -4
  88. package/lib/app/observer/iframe_observer.js +0 -18
  89. package/lib/app/observer/observer.d.ts +0 -46
  90. package/lib/app/observer/observer.js +0 -348
  91. package/lib/app/observer/shadow_root_observer.d.ts +0 -4
  92. package/lib/app/observer/shadow_root_observer.js +0 -18
  93. package/lib/app/observer/top_observer.d.ts +0 -15
  94. package/lib/app/observer/top_observer.js +0 -75
@@ -1,2 +1,2 @@
1
- import App from '../app';
1
+ import App from "../app/index.js";
2
2
  export default function (app: App): void;
@@ -1,4 +1,4 @@
1
- import { LongTask } from '../messages';
1
+ import { LongTask } from "../messages/index.js";
2
2
  ;
3
3
  ;
4
4
  export default function (app) {
@@ -1,2 +1,2 @@
1
- import App from '../app';
1
+ import App from "../app/index.js";
2
2
  export default function (app: App): void;
@@ -1,6 +1,6 @@
1
- import { normSpaces, hasOpenreplayAttribute, getLabelAttribute } from '../utils';
2
- import { MouseMove, MouseClick } from '../messages';
3
- import { getInputLabel } from './input';
1
+ import { normSpaces, hasOpenreplayAttribute, getLabelAttribute } from "../utils.js";
2
+ import { MouseMove, MouseClick } from "../messages/index.js";
3
+ import { getInputLabel } from "./input.js";
4
4
  function _getSelector(target) {
5
5
  let el = target;
6
6
  let selector = null;
@@ -1,4 +1,4 @@
1
- import App from '../app';
1
+ import App from "../app/index.js";
2
2
  export declare const deviceMemory: number;
3
3
  export declare const jsHeapSizeLimit: number;
4
4
  export interface Options {
@@ -1,5 +1,5 @@
1
- import { IN_BROWSER } from '../utils';
2
- import { PerformanceTrack } from '../messages';
1
+ import { IN_BROWSER } from "../utils.js";
2
+ import { PerformanceTrack } from "../messages/index.js";
3
3
  const perf = IN_BROWSER && 'performance' in window && 'memory' in performance // works in Chrome only
4
4
  ? performance
5
5
  : { memory: {} };
@@ -1,2 +1,2 @@
1
- import App from '../app';
1
+ import App from "../app/index.js";
2
2
  export default function (app: App): void;
@@ -1,4 +1,4 @@
1
- import { SetViewportScroll, SetNodeScroll } from '../messages';
1
+ import { SetViewportScroll, SetNodeScroll } from "../messages/index.js";
2
2
  export default function (app) {
3
3
  let documentScroll = false;
4
4
  const nodeScroll = new Map();
@@ -1,4 +1,4 @@
1
- import App from '../app';
1
+ import App from "../app/index.js";
2
2
  export interface Options {
3
3
  captureResourceTimings: boolean;
4
4
  capturePageLoadTimings: boolean;
@@ -1,5 +1,5 @@
1
- import { isURL } from '../utils';
2
- import { ResourceTiming, PageLoadTiming, PageRenderTiming } from '../messages';
1
+ import { isURL } from "../utils.js";
2
+ import { ResourceTiming, PageLoadTiming, PageRenderTiming } from "../messages/index.js";
3
3
  function getPaintBlocks(resources) {
4
4
  const paintBlocks = [];
5
5
  const elements = document.getElementsByTagName('*');
@@ -1,2 +1,2 @@
1
- import App from '../app';
1
+ import App from "../app/index.js";
2
2
  export default function (app: App): void;
@@ -1,4 +1,4 @@
1
- import { SetPageLocation, SetViewportSize, SetPageVisibility, } from '../messages';
1
+ import { SetPageLocation, SetViewportSize, SetPageVisibility, } from "../messages/index.js";
2
2
  export default function (app) {
3
3
  let url, width, height;
4
4
  let navigationStart = performance.timing.navigationStart;
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.4.7",
4
+ "version": "3.4.11",
5
5
  "keywords": [
6
6
  "logging",
7
7
  "replay"
@@ -35,7 +35,7 @@
35
35
  "rollup": "^2.17.0",
36
36
  "rollup-plugin-terser": "^6.1.0",
37
37
  "semver": "^6.3.0",
38
- "typescript": "^4.3.4"
38
+ "typescript": "^4.6.0-dev.20211126"
39
39
  },
40
40
  "dependencies": {
41
41
  "error-stack-parser": "^2.0.6"
@@ -9,6 +9,6 @@
9
9
  "alwaysStrict": true,
10
10
  "target": "es6",
11
11
  "module": "es6",
12
- "moduleResolution": "node"
12
+ "moduleResolution": "nodenext"
13
13
  }
14
14
  }
@@ -1,4 +0,0 @@
1
- import Observer from './observer';
2
- export default class IFrameObserver extends Observer {
3
- observe(iframe: HTMLIFrameElement): void;
4
- }
@@ -1,21 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const observer_1 = require("./observer");
4
- const messages_1 = require("../../messages");
5
- class IFrameObserver extends observer_1.default {
6
- observe(iframe) {
7
- const doc = iframe.contentDocument;
8
- const frameID = this.app.nodes.getID(iframe);
9
- if (!doc || frameID === undefined) {
10
- return;
11
- } //log TODO common app.logger
12
- this.observeRoot(doc, (docID) => {
13
- if (docID === undefined) {
14
- console.log("OpenReplay: Document not bound");
15
- return;
16
- }
17
- this.app.send(messages_1.CreateIFrameDocument(frameID, docID));
18
- });
19
- }
20
- }
21
- exports.default = IFrameObserver;
@@ -1,46 +0,0 @@
1
- import App from '../index';
2
- export interface Window extends globalThis.Window {
3
- HTMLInputElement: typeof HTMLInputElement;
4
- HTMLLinkElement: typeof HTMLLinkElement;
5
- HTMLStyleElement: typeof HTMLStyleElement;
6
- SVGStyleElement: typeof SVGStyleElement;
7
- HTMLIFrameElement: typeof HTMLIFrameElement;
8
- Text: typeof Text;
9
- Element: typeof Element;
10
- ShadowRoot: typeof ShadowRoot;
11
- }
12
- declare type WindowConstructor = Document | Element | Text | ShadowRoot | HTMLInputElement | HTMLLinkElement | HTMLStyleElement | HTMLIFrameElement;
13
- declare type Constructor<T> = {
14
- new (...args: any[]): T;
15
- name: string;
16
- };
17
- export declare function isInstance<T extends WindowConstructor>(node: Node, constr: Constructor<T>): node is T;
18
- export interface Options {
19
- obscureTextEmails: boolean;
20
- obscureTextNumbers: boolean;
21
- }
22
- export default abstract class Observer<AdditionalOptions = {}> {
23
- protected readonly app: App;
24
- protected readonly context: Window;
25
- private readonly observer;
26
- private readonly commited;
27
- private readonly recents;
28
- private readonly indexes;
29
- private readonly attributesList;
30
- private readonly textSet;
31
- private readonly textMasked;
32
- protected readonly options: Options & AdditionalOptions;
33
- constructor(app: App, options: Partial<Options> & AdditionalOptions, context?: Window);
34
- private clear;
35
- private sendNodeAttribute;
36
- private sendNodeData;
37
- private bindNode;
38
- private bindTree;
39
- private unbindNode;
40
- private _commitNode;
41
- private commitNode;
42
- private commitNodes;
43
- protected observeRoot(node: Node, beforeCommit: (id?: number) => unknown): void;
44
- disconnect(): void;
45
- }
46
- export {};
@@ -1,353 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isInstance = void 0;
4
- const utils_1 = require("../../utils");
5
- const messages_1 = require("../../messages");
6
- function isSVGElement(node) {
7
- return node.namespaceURI === 'http://www.w3.org/2000/svg';
8
- }
9
- // TODO: we need a type expert here so we won't have to ignore the lines
10
- // TODO: use it everywhere (static function; export from which file? <-- global Window typing required)
11
- function isInstance(node, constr) {
12
- const doc = node.ownerDocument;
13
- if (!doc) { // null if Document
14
- return constr.name === 'Document';
15
- }
16
- let context =
17
- // @ts-ignore (for EI, Safary)
18
- doc.parentWindow ||
19
- doc.defaultView; // TODO: smart global typing for Window object
20
- while (context.parent && context.parent !== context) {
21
- // @ts-ignore
22
- if (node instanceof context[constr.name]) {
23
- return true;
24
- }
25
- // @ts-ignore
26
- context = context.parent;
27
- }
28
- // @ts-ignore
29
- return node instanceof context[constr.name];
30
- }
31
- exports.isInstance = isInstance;
32
- function isIgnored(node) {
33
- if (isInstance(node, Text)) {
34
- return false;
35
- }
36
- if (!isInstance(node, Element)) {
37
- return true;
38
- }
39
- const tag = node.tagName.toUpperCase();
40
- if (tag === 'LINK') {
41
- const rel = node.getAttribute('rel');
42
- const as = node.getAttribute('as');
43
- return !((rel === null || rel === void 0 ? void 0 : rel.includes('stylesheet')) || as === "style" || as === "font");
44
- }
45
- return (tag === 'SCRIPT' ||
46
- tag === 'NOSCRIPT' ||
47
- tag === 'META' ||
48
- tag === 'TITLE' ||
49
- tag === 'BASE');
50
- }
51
- function isRootNode(node) {
52
- return isInstance(node, Document) || isInstance(node, ShadowRoot);
53
- }
54
- function isObservable(node) {
55
- if (isRootNode(node)) {
56
- return true;
57
- }
58
- return !isIgnored(node);
59
- }
60
- class Observer {
61
- constructor(app, options, context = window) {
62
- this.app = app;
63
- this.context = context;
64
- this.options = Object.assign({
65
- obscureTextEmails: true,
66
- obscureTextNumbers: false,
67
- }, options);
68
- this.observer = new MutationObserver(this.app.safe((mutations) => {
69
- for (const mutation of mutations) {
70
- const target = mutation.target;
71
- const type = mutation.type;
72
- // TODO TODO TODO: move to iframe_observer/remove??? (check if )
73
- // Special case
74
- // 'childList' on Document might happen in case of iframe.
75
- // TODO: generalize as much as possible
76
- // if (isInstance(target, Document) // Also ShadowRoot can be here
77
- // && type === 'childList'
78
- // //&& new Array(mutation.addedNodes).some(node => isInstance(node, HTMLHtmlElement))
79
- // ) {
80
- // const parentFrame = target.defaultView?.frameElement
81
- // if (!parentFrame) { continue }
82
- // this.bindTree(target.documentElement)
83
- // const frameID = this.app.nodes.getID(parentFrame)
84
- // const docID = this.app.nodes.getID(target.documentElement)
85
- // if (frameID === undefined || docID === undefined) { continue }
86
- // this.app.send(CreateIFrameDocument(frameID, docID));
87
- // continue;
88
- // }
89
- if (!isObservable(target) || !context.document.contains(target)) {
90
- continue;
91
- }
92
- if (type === 'childList') {
93
- for (let i = 0; i < mutation.removedNodes.length; i++) {
94
- this.bindTree(mutation.removedNodes[i]);
95
- }
96
- for (let i = 0; i < mutation.addedNodes.length; i++) {
97
- this.bindTree(mutation.addedNodes[i]);
98
- }
99
- continue;
100
- }
101
- const id = this.app.nodes.getID(target);
102
- if (id === undefined) {
103
- continue;
104
- }
105
- if (id >= this.recents.length) {
106
- this.recents[id] = undefined;
107
- }
108
- if (type === 'attributes') {
109
- const name = mutation.attributeName;
110
- if (name === null) {
111
- continue;
112
- }
113
- let attr = this.attributesList[id];
114
- if (attr === undefined) {
115
- this.attributesList[id] = attr = new Set();
116
- }
117
- attr.add(name);
118
- continue;
119
- }
120
- if (type === 'characterData') {
121
- this.textSet.add(id);
122
- continue;
123
- }
124
- }
125
- this.commitNodes();
126
- }));
127
- this.commited = [];
128
- this.recents = [];
129
- this.indexes = [0];
130
- this.attributesList = [];
131
- this.textSet = new Set();
132
- this.textMasked = new Set();
133
- }
134
- clear() {
135
- this.commited.length = 0;
136
- this.recents.length = 0;
137
- this.indexes.length = 1;
138
- this.attributesList.length = 0;
139
- this.textSet.clear();
140
- this.textMasked.clear();
141
- }
142
- sendNodeAttribute(id, node, name, value) {
143
- if (isSVGElement(node)) {
144
- if (name.substr(0, 6) === 'xlink:') {
145
- name = name.substr(6);
146
- }
147
- if (value === null) {
148
- this.app.send(new messages_1.RemoveNodeAttribute(id, name));
149
- }
150
- else if (name === 'href') {
151
- if (value.length > 1e5) {
152
- value = '';
153
- }
154
- this.app.send(new messages_1.SetNodeAttributeURLBased(id, name, value, this.app.getBaseHref()));
155
- }
156
- else {
157
- this.app.send(new messages_1.SetNodeAttribute(id, name, value));
158
- }
159
- return;
160
- }
161
- if (name === 'src' ||
162
- name === 'srcset' ||
163
- name === 'integrity' ||
164
- name === 'crossorigin' ||
165
- name === 'autocomplete' ||
166
- name.substr(0, 2) === 'on') {
167
- return;
168
- }
169
- if (name === 'value' &&
170
- isInstance(node, HTMLInputElement) &&
171
- node.type !== 'button' &&
172
- node.type !== 'reset' &&
173
- node.type !== 'submit') {
174
- return;
175
- }
176
- if (value === null) {
177
- this.app.send(new messages_1.RemoveNodeAttribute(id, name));
178
- return;
179
- }
180
- if (name === 'style' || name === 'href' && isInstance(node, HTMLLinkElement)) {
181
- this.app.send(new messages_1.SetNodeAttributeURLBased(id, name, value, this.app.getBaseHref()));
182
- return;
183
- }
184
- if (name === 'href' || value.length > 1e5) {
185
- value = '';
186
- }
187
- this.app.send(new messages_1.SetNodeAttribute(id, name, value));
188
- }
189
- sendNodeData(id, parentElement, data) {
190
- if (isInstance(parentElement, HTMLStyleElement) || isInstance(parentElement, SVGStyleElement)) {
191
- this.app.send(new messages_1.SetCSSDataURLBased(id, data, this.app.getBaseHref()));
192
- return;
193
- }
194
- if (this.textMasked.has(id)) {
195
- data = data.replace(/[^\f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]/g, '█');
196
- }
197
- else {
198
- if (this.options.obscureTextNumbers) {
199
- data = data.replace(/\d/g, '0');
200
- }
201
- if (this.options.obscureTextEmails) {
202
- data = data.replace(/([^\s]+)@([^\s]+)\.([^\s]+)/g, (...f) => utils_1.stars(f[1]) + '@' + utils_1.stars(f[2]) + '.' + utils_1.stars(f[3]));
203
- }
204
- }
205
- this.app.send(new messages_1.SetNodeData(id, data));
206
- }
207
- bindNode(node) {
208
- const r = this.app.nodes.registerNode(node);
209
- const id = r[0];
210
- this.recents[id] = r[1] || this.recents[id] || false;
211
- }
212
- bindTree(node) {
213
- if (!isObservable(node)) {
214
- return;
215
- }
216
- this.bindNode(node);
217
- const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT + NodeFilter.SHOW_TEXT, {
218
- acceptNode: (node) => isIgnored(node) || this.app.nodes.getID(node) !== undefined
219
- ? NodeFilter.FILTER_REJECT
220
- : NodeFilter.FILTER_ACCEPT,
221
- }, false);
222
- while (walker.nextNode()) {
223
- this.bindNode(walker.currentNode);
224
- }
225
- }
226
- unbindNode(node) {
227
- const id = this.app.nodes.unregisterNode(node);
228
- if (id !== undefined && this.recents[id] === false) {
229
- this.app.send(new messages_1.RemoveNode(id));
230
- }
231
- }
232
- _commitNode(id, node) {
233
- if (isRootNode(node)) {
234
- return true;
235
- }
236
- const parent = node.parentNode;
237
- let parentID;
238
- // if (isInstance(node, HTMLHtmlElement)) { // ?? TODO: get rid of "specia" cases
239
- // this.indexes[id] = 0
240
- // } else {
241
- if (parent === null) {
242
- this.unbindNode(node);
243
- return false;
244
- }
245
- parentID = this.app.nodes.getID(parent);
246
- if (parentID === undefined) {
247
- this.unbindNode(node);
248
- return false;
249
- }
250
- if (!this.commitNode(parentID)) {
251
- this.unbindNode(node);
252
- return false;
253
- }
254
- if (this.textMasked.has(parentID) ||
255
- (isInstance(node, Element) && utils_1.hasOpenreplayAttribute(node, 'masked'))) {
256
- this.textMasked.add(id);
257
- }
258
- let sibling = node.previousSibling;
259
- while (sibling !== null) {
260
- const siblingID = this.app.nodes.getID(sibling);
261
- if (siblingID !== undefined) {
262
- this.commitNode(siblingID);
263
- this.indexes[id] = this.indexes[siblingID] + 1;
264
- break;
265
- }
266
- sibling = sibling.previousSibling;
267
- }
268
- if (sibling === null) {
269
- this.indexes[id] = 0;
270
- }
271
- const isNew = this.recents[id];
272
- const index = this.indexes[id];
273
- if (index === undefined) {
274
- throw 'commitNode: missing node index';
275
- }
276
- if (isNew === true) {
277
- if (isInstance(node, Element)) {
278
- if (parentID !== undefined) {
279
- this.app.send(new messages_1.CreateElementNode(id, parentID, index, node.tagName, isSVGElement(node)));
280
- }
281
- for (let i = 0; i < node.attributes.length; i++) {
282
- const attr = node.attributes[i];
283
- this.sendNodeAttribute(id, node, attr.nodeName, attr.value);
284
- }
285
- }
286
- else if (isInstance(node, Text)) {
287
- // for text node id != 0, hence parentID !== undefined and parent is Element
288
- this.app.send(new messages_1.CreateTextNode(id, parentID, index));
289
- this.sendNodeData(id, parent, node.data);
290
- }
291
- return true;
292
- }
293
- if (isNew === false && parentID !== undefined) {
294
- this.app.send(new messages_1.MoveNode(id, parentID, index));
295
- }
296
- const attr = this.attributesList[id];
297
- if (attr !== undefined) {
298
- if (!isInstance(node, Element)) {
299
- throw 'commitNode: node is not an element';
300
- }
301
- for (const name of attr) {
302
- this.sendNodeAttribute(id, node, name, node.getAttribute(name));
303
- }
304
- }
305
- if (this.textSet.has(id)) {
306
- if (!isInstance(node, Text)) {
307
- throw 'commitNode: node is not a text';
308
- }
309
- // for text node id != 0, hence parent is Element
310
- this.sendNodeData(id, parent, node.data);
311
- }
312
- return true;
313
- }
314
- commitNode(id) {
315
- const node = this.app.nodes.getNode(id);
316
- if (node === undefined) {
317
- return false;
318
- }
319
- const cmt = this.commited[id];
320
- if (cmt !== undefined) {
321
- return cmt;
322
- }
323
- return (this.commited[id] = this._commitNode(id, node));
324
- }
325
- commitNodes() {
326
- let node;
327
- for (let id = 0; id < this.recents.length; id++) {
328
- this.commitNode(id);
329
- if (this.recents[id] === true && (node = this.app.nodes.getNode(id))) {
330
- this.app.nodes.callNodeCallbacks(node);
331
- }
332
- }
333
- this.clear();
334
- }
335
- observeRoot(node, beforeCommit) {
336
- this.observer.observe(node, {
337
- childList: true,
338
- attributes: true,
339
- characterData: true,
340
- subtree: true,
341
- attributeOldValue: false,
342
- characterDataOldValue: false,
343
- });
344
- this.bindTree(node);
345
- beforeCommit(this.app.nodes.getID(node));
346
- this.commitNodes();
347
- }
348
- disconnect() {
349
- this.observer.disconnect();
350
- this.clear();
351
- }
352
- }
353
- exports.default = Observer;
@@ -1,4 +0,0 @@
1
- import Observer from './observer';
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_1 = require("./observer");
4
- const messages_1 = require("../../messages");
5
- class ShadowRootObserver extends observer_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(messages_1.CreateIFrameDocument(hostID, rootID));
18
- });
19
- }
20
- }
21
- exports.default = ShadowRootObserver;
@@ -1,15 +0,0 @@
1
- import Observer from './observer';
2
- import type { Options as BaseOptions } from './observer';
3
- import type App from '../index';
4
- export interface Options extends Partial<BaseOptions> {
5
- captureIFrames: boolean;
6
- }
7
- export default class TopObserver extends Observer<Options> {
8
- constructor(app: App, options: Partial<Options>);
9
- private iframeObservers;
10
- private handleIframe;
11
- private shadowRootObservers;
12
- private handleShadowRoot;
13
- observe(): void;
14
- disconnect(): void;
15
- }
@@ -1,78 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const observer_1 = require("./observer");
4
- const iframe_observer_1 = require("./iframe_observer");
5
- const shadow_root_observer_1 = require("./shadow_root_observer");
6
- const messages_1 = require("../../messages");
7
- class TopObserver extends observer_1.default {
8
- constructor(app, options) {
9
- super(app, Object.assign({
10
- captureIFrames: false
11
- }, options));
12
- this.iframeObservers = [];
13
- this.shadowRootObservers = [];
14
- // IFrames
15
- this.app.nodes.attachNodeCallback(node => {
16
- if (observer_1.isInstance(node, HTMLIFrameElement) &&
17
- (this.options.captureIFrames || node.getAttribute("data-openreplay-capture"))) {
18
- this.handleIframe(node);
19
- }
20
- });
21
- // ShadowDOM
22
- this.app.nodes.attachNodeCallback(node => {
23
- if (observer_1.isInstance(node, Element) && node.shadowRoot !== null) {
24
- this.handleShadowRoot(node.shadowRoot);
25
- }
26
- });
27
- const attachShadowNative = Element.prototype.attachShadow;
28
- const observer = this;
29
- Element.prototype.attachShadow = function () {
30
- const shadow = attachShadowNative.apply(this, arguments);
31
- if (app.active()) { // Is it necessary here?
32
- // TODO: clearify logic - sub-observation should happen only during main observation.
33
- // THat works well with node callbacks, but not here
34
- observer.handleShadowRoot(shadow);
35
- }
36
- return shadow;
37
- };
38
- }
39
- handleIframe(iframe) {
40
- let context = null;
41
- const handle = () => {
42
- const id = this.app.nodes.getID(iframe);
43
- if (id === undefined) {
44
- return;
45
- } //log
46
- if (iframe.contentWindow === context) {
47
- return;
48
- } //Does this happen frequently?
49
- context = iframe.contentWindow;
50
- if (!context) {
51
- return;
52
- }
53
- const observer = new iframe_observer_1.default(this.app, this.options, context);
54
- this.iframeObservers.push(observer);
55
- observer.observe(iframe);
56
- };
57
- this.app.attachEventListener(iframe, "load", handle);
58
- handle();
59
- }
60
- handleShadowRoot(shRoot) {
61
- const observer = new shadow_root_observer_1.default(this.app, this.options, this.context);
62
- this.shadowRootObservers.push(observer);
63
- observer.observe(shRoot.host);
64
- }
65
- observe() {
66
- this.observeRoot(this.context.document, () => {
67
- this.app.send(new messages_1.CreateDocument());
68
- });
69
- }
70
- disconnect() {
71
- this.iframeObservers.forEach(o => o.disconnect());
72
- this.iframeObservers = [];
73
- this.shadowRootObservers.forEach(o => o.disconnect());
74
- this.shadowRootObservers = [];
75
- super.disconnect();
76
- }
77
- }
78
- exports.default = TopObserver;
@@ -1,4 +0,0 @@
1
- import Observer from './observer';
2
- export default class IFrameObserver extends Observer {
3
- observe(iframe: HTMLIFrameElement): void;
4
- }