@highlight-run/rrweb 1.2.1 → 2.0.4

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 (191) hide show
  1. package/dist/plugins/console-record.js +454 -0
  2. package/dist/plugins/console-record.min.js +12 -15
  3. package/dist/plugins/console-record.min.js.map +1 -1
  4. package/dist/plugins/console-replay.js +164 -0
  5. package/dist/plugins/console-replay.min.js +5 -0
  6. package/dist/plugins/console-replay.min.js.map +1 -0
  7. package/dist/plugins/sequential-id-record.js +30 -0
  8. package/dist/plugins/sequential-id-record.min.js +2 -0
  9. package/dist/plugins/sequential-id-record.min.js.map +1 -0
  10. package/dist/plugins/sequential-id-replay.js +33 -0
  11. package/dist/plugins/sequential-id-replay.min.js +2 -0
  12. package/dist/plugins/sequential-id-replay.min.js.map +1 -0
  13. package/dist/record/rrweb-record-pack.js +664 -0
  14. package/dist/record/rrweb-record-pack.min.js +4 -0
  15. package/dist/record/rrweb-record-pack.min.js.map +1 -0
  16. package/dist/record/rrweb-record.js +3202 -0
  17. package/dist/record/rrweb-record.min.js +5 -0
  18. package/dist/record/rrweb-record.min.js.map +1 -0
  19. package/dist/replay/rrweb-replay-unpack.js +4926 -0
  20. package/dist/replay/rrweb-replay-unpack.min.js +18 -0
  21. package/dist/replay/rrweb-replay-unpack.min.js.map +1 -0
  22. package/dist/replay/rrweb-replay.js +4518 -0
  23. package/dist/replay/rrweb-replay.min.js +18 -0
  24. package/dist/replay/rrweb-replay.min.js.map +1 -0
  25. package/dist/rrweb-all.js +8889 -0
  26. package/dist/rrweb-all.min.js +29 -0
  27. package/dist/rrweb-all.min.js.map +1 -0
  28. package/dist/rrweb.js +7558 -0
  29. package/dist/rrweb.min.js +6 -17
  30. package/dist/rrweb.min.js.map +1 -1
  31. package/es/rrweb/_virtual/_rollup-plugin-web-worker-loader__helper__auto__createBase64WorkerFactory.js +12 -0
  32. package/es/rrweb/_virtual/_rollup-plugin-web-worker-loader__helper__auto__isNodeJS.js +7 -0
  33. package/es/rrweb/_virtual/_rollup-plugin-web-worker-loader__helper__browser__createBase64WorkerFactory.js +31 -0
  34. package/es/rrweb/_virtual/_rollup-plugin-web-worker-loader__helper__node__WorkerClass.js +11 -0
  35. package/es/rrweb/_virtual/_rollup-plugin-web-worker-loader__helper__node__createBase64WorkerFactory.js +18 -0
  36. package/es/rrweb/_virtual/image-bitmap-data-url-worker.js +6 -0
  37. package/es/rrweb/ext/@xstate/fsm/es/index.js +17 -0
  38. package/es/rrweb/ext/base64-arraybuffer/dist/base64-arraybuffer.es5.js +49 -0
  39. package/es/rrweb/ext/fflate/esm/browser.js +777 -0
  40. package/es/rrweb/ext/mitt/dist/mitt.es.js +63 -0
  41. package/es/rrweb/ext/tslib/tslib.es6.js +38 -0
  42. package/es/rrweb/packages/rrdom/es/virtual-dom.js +1099 -0
  43. package/es/rrweb/packages/rrweb/src/entries/all.js +13 -0
  44. package/es/rrweb/packages/rrweb/src/index.js +14 -0
  45. package/es/rrweb/packages/rrweb/src/packer/base.js +3 -0
  46. package/es/rrweb/packages/rrweb/src/packer/pack.js +9 -0
  47. package/es/rrweb/packages/rrweb/src/packer/unpack.js +29 -0
  48. package/es/rrweb/packages/rrweb/src/plugins/console/record/error-stack-parser.js +178 -0
  49. package/es/rrweb/packages/rrweb/src/plugins/console/record/index.js +115 -0
  50. package/es/rrweb/packages/rrweb/src/plugins/console/record/stringify.js +128 -0
  51. package/es/rrweb/packages/rrweb/src/plugins/console/replay/index.js +94 -0
  52. package/es/rrweb/packages/rrweb/src/plugins/sequential-id/record/index.js +22 -0
  53. package/es/rrweb/packages/rrweb/src/plugins/sequential-id/replay/index.js +28 -0
  54. package/es/rrweb/packages/rrweb/src/record/iframe-manager.js +31 -0
  55. package/es/rrweb/packages/rrweb/src/record/index.js +356 -0
  56. package/es/rrweb/packages/rrweb/src/record/mutation.js +491 -0
  57. package/es/rrweb/packages/rrweb/src/record/observer.js +590 -0
  58. package/es/rrweb/packages/rrweb/src/record/observers/canvas/2d.js +49 -0
  59. package/es/rrweb/packages/rrweb/src/record/observers/canvas/canvas-manager.js +172 -0
  60. package/es/rrweb/packages/rrweb/src/record/observers/canvas/canvas.js +25 -0
  61. package/es/rrweb/packages/rrweb/src/record/observers/canvas/serialize-args.js +123 -0
  62. package/es/rrweb/packages/rrweb/src/record/observers/canvas/webgl.js +59 -0
  63. package/es/rrweb/packages/rrweb/src/record/shadow-dom-manager.js +43 -0
  64. package/es/rrweb/packages/rrweb/src/record/stylesheet-manager.js +31 -0
  65. package/es/rrweb/packages/rrweb/src/replay/canvas/2d.js +29 -0
  66. package/es/rrweb/packages/rrweb/src/replay/canvas/deserialize-args.js +67 -0
  67. package/es/rrweb/packages/rrweb/src/replay/canvas/index.js +43 -0
  68. package/es/rrweb/packages/rrweb/src/replay/canvas/webgl.js +62 -0
  69. package/es/rrweb/packages/rrweb/src/replay/index.js +1555 -0
  70. package/es/rrweb/packages/rrweb/src/replay/machine.js +281 -0
  71. package/es/rrweb/packages/rrweb/src/replay/smoothscroll.js +219 -0
  72. package/es/rrweb/packages/rrweb/src/replay/styles/inject-style.js +8 -0
  73. package/es/rrweb/packages/rrweb/src/replay/timer.js +92 -0
  74. package/es/rrweb/packages/rrweb/src/types.js +75 -0
  75. package/es/rrweb/packages/rrweb/src/utils.js +315 -0
  76. package/es/rrweb/packages/rrweb-snapshot/es/rrweb-snapshot.js +1821 -0
  77. package/lib/plugins/console-record.js +492 -0
  78. package/lib/plugins/console-replay.js +218 -0
  79. package/lib/plugins/sequential-id-record.js +27 -0
  80. package/lib/plugins/sequential-id-replay.js +32 -0
  81. package/lib/record/rrweb-record-pack.js +787 -0
  82. package/lib/record/rrweb-record.js +3363 -0
  83. package/lib/replay/rrweb-replay-unpack.js +5075 -0
  84. package/lib/replay/rrweb-replay.js +4665 -0
  85. package/lib/rrweb-all.js +9181 -0
  86. package/lib/rrweb.js +7814 -0
  87. package/package.json +41 -42
  88. package/typings/entries/all.d.ts +6 -0
  89. package/{dist → typings}/entries/record-pack.d.ts +0 -0
  90. package/{dist → typings}/entries/replay-unpack.d.ts +0 -0
  91. package/{dist → typings}/index.d.ts +1 -2
  92. package/{dist → typings}/packer/base.d.ts +1 -1
  93. package/{dist → typings}/packer/index.d.ts +0 -0
  94. package/{dist → typings}/packer/pack.d.ts +0 -0
  95. package/{dist → typings}/packer/unpack.d.ts +0 -0
  96. package/{dist → typings}/plugins/console/record/error-stack-parser.d.ts +0 -0
  97. package/{dist → typings}/plugins/console/record/index.d.ts +4 -3
  98. package/{dist → typings}/plugins/console/record/stringify.d.ts +1 -1
  99. package/{dist → typings}/plugins/console/replay/index.d.ts +2 -2
  100. package/{dist → typings}/plugins/sequential-id/record/index.d.ts +1 -1
  101. package/{dist → typings}/plugins/sequential-id/replay/index.d.ts +1 -1
  102. package/{dist → typings}/record/iframe-manager.d.ts +3 -3
  103. package/{dist/plugins → typings}/record/index.d.ts +9 -9
  104. package/{dist → typings}/record/mutation.d.ts +6 -8
  105. package/typings/record/observer.d.ts +7 -0
  106. package/{dist/plugins → typings}/record/observers/canvas/2d.d.ts +3 -2
  107. package/{dist → typings}/record/observers/canvas/canvas-manager.d.ts +5 -2
  108. package/{dist/plugins → typings}/record/observers/canvas/canvas.d.ts +2 -2
  109. package/typings/record/observers/canvas/serialize-args.d.ts +6 -0
  110. package/{dist/plugins → typings}/record/observers/canvas/webgl.d.ts +3 -2
  111. package/typings/record/observers/canvas/webgl2.d.ts +2 -0
  112. package/typings/record/shadow-dom-manager.d.ts +22 -0
  113. package/typings/record/stylesheet-manager.d.ts +12 -0
  114. package/typings/record/workers/image-bitmap-data-url-worker.d.ts +5 -0
  115. package/{dist → typings}/replay/canvas/2d.d.ts +3 -3
  116. package/typings/replay/canvas/deserialize-args.d.ts +7 -0
  117. package/{dist/plugins → typings}/replay/canvas/index.d.ts +10 -9
  118. package/typings/replay/canvas/webgl.d.ts +9 -0
  119. package/{dist → typings}/replay/index.d.ts +7 -9
  120. package/{dist → typings}/replay/machine.d.ts +0 -0
  121. package/{dist → typings}/replay/smoothscroll.d.ts +0 -0
  122. package/{dist → typings}/replay/styles/inject-style.d.ts +0 -0
  123. package/{dist → typings}/replay/timer.d.ts +0 -0
  124. package/{dist → typings}/rrdom/index.d.ts +0 -0
  125. package/{dist → typings}/rrdom/tree-node.d.ts +0 -0
  126. package/{dist/plugins → typings}/types.d.ts +536 -509
  127. package/typings/utils.d.ts +43 -0
  128. package/CHANGELOG.md +0 -26
  129. package/README.md +0 -124
  130. package/README.zh_CN.md +0 -122
  131. package/dist/entries/all.d.ts +0 -4
  132. package/dist/index.css +0 -82
  133. package/dist/index.css.map +0 -1
  134. package/dist/index.js +0 -3
  135. package/dist/index.js.LICENSE.txt +0 -14
  136. package/dist/index.js.map +0 -1
  137. package/dist/plugins/entries/all.d.ts +0 -4
  138. package/dist/plugins/entries/record-pack.d.ts +0 -2
  139. package/dist/plugins/entries/replay-unpack.d.ts +0 -2
  140. package/dist/plugins/index.d.ts +0 -9
  141. package/dist/plugins/packer/base.d.ts +0 -7
  142. package/dist/plugins/packer/index.d.ts +0 -2
  143. package/dist/plugins/packer/pack.d.ts +0 -2
  144. package/dist/plugins/packer/unpack.d.ts +0 -2
  145. package/dist/plugins/plugins/console/record/error-stack-parser.d.ts +0 -37
  146. package/dist/plugins/plugins/console/record/index.d.ts +0 -41
  147. package/dist/plugins/plugins/console/record/stringify.d.ts +0 -2
  148. package/dist/plugins/plugins/console/replay/index.d.ts +0 -9
  149. package/dist/plugins/plugins/sequential-id/record/index.d.ts +0 -6
  150. package/dist/plugins/plugins/sequential-id/replay/index.d.ts +0 -7
  151. package/dist/plugins/record/iframe-manager.d.ts +0 -13
  152. package/dist/plugins/record/mutation.d.ts +0 -45
  153. package/dist/plugins/record/observer.d.ts +0 -11
  154. package/dist/plugins/record/observers/canvas/canvas-manager.d.ts +0 -32
  155. package/dist/plugins/record/observers/canvas/serialize-args.d.ts +0 -6
  156. package/dist/plugins/record/shadow-dom-manager.d.ts +0 -34
  157. package/dist/plugins/replay/canvas/2d.d.ts +0 -9
  158. package/dist/plugins/replay/canvas/webgl.d.ts +0 -11
  159. package/dist/plugins/replay/index.d.ts +0 -82
  160. package/dist/plugins/replay/machine.d.ts +0 -85
  161. package/dist/plugins/replay/smoothscroll.d.ts +0 -1
  162. package/dist/plugins/replay/styles/inject-style.d.ts +0 -2
  163. package/dist/plugins/replay/timer.d.ts +0 -19
  164. package/dist/plugins/replay/virtual-styles.d.ts +0 -43
  165. package/dist/plugins/rrdom/index.d.ts +0 -1
  166. package/dist/plugins/rrdom/tree-node.d.ts +0 -20
  167. package/dist/plugins/snapshot/css.d.ts +0 -92
  168. package/dist/plugins/snapshot/index.d.ts +0 -5
  169. package/dist/plugins/snapshot/rebuild.d.ts +0 -19
  170. package/dist/plugins/snapshot/snapshot.d.ts +0 -49
  171. package/dist/plugins/snapshot/types.d.ts +0 -99
  172. package/dist/plugins/snapshot/utils.d.ts +0 -11
  173. package/dist/plugins/utils.d.ts +0 -71
  174. package/dist/record/index.d.ts +0 -9
  175. package/dist/record/observer.d.ts +0 -11
  176. package/dist/record/observers/canvas/2d.d.ts +0 -2
  177. package/dist/record/observers/canvas/canvas.d.ts +0 -2
  178. package/dist/record/observers/canvas/serialize-args.d.ts +0 -6
  179. package/dist/record/observers/canvas/webgl.d.ts +0 -2
  180. package/dist/record/shadow-dom-manager.d.ts +0 -34
  181. package/dist/replay/canvas/index.d.ts +0 -9
  182. package/dist/replay/canvas/webgl.d.ts +0 -11
  183. package/dist/replay/virtual-styles.d.ts +0 -43
  184. package/dist/snapshot/css.d.ts +0 -92
  185. package/dist/snapshot/index.d.ts +0 -5
  186. package/dist/snapshot/rebuild.d.ts +0 -19
  187. package/dist/snapshot/snapshot.d.ts +0 -49
  188. package/dist/snapshot/types.d.ts +0 -99
  189. package/dist/snapshot/utils.d.ts +0 -11
  190. package/dist/types.d.ts +0 -509
  191. package/dist/utils.d.ts +0 -71
@@ -0,0 +1,590 @@
1
+ import { maskInputValue } from '../../../rrweb-snapshot/es/rrweb-snapshot.js';
2
+ import { on, throttle, isBlocked, getWindowHeight, getWindowWidth, hookSetter, patch, isTouchEvent, isCanvasNode } from '../utils.js';
3
+ import { MouseInteractions, IncrementalSource } from '../types.js';
4
+ import MutationBuffer from './mutation.js';
5
+
6
+ const mutationBuffers = [];
7
+ const isCSSGroupingRuleSupported = typeof CSSGroupingRule !== 'undefined';
8
+ const isCSSMediaRuleSupported = typeof CSSMediaRule !== 'undefined';
9
+ const isCSSSupportsRuleSupported = typeof CSSSupportsRule !== 'undefined';
10
+ const isCSSConditionRuleSupported = typeof CSSConditionRule !== 'undefined';
11
+ function getEventTarget(event) {
12
+ try {
13
+ if ('composedPath' in event) {
14
+ const path = event.composedPath();
15
+ if (path.length) {
16
+ return path[0];
17
+ }
18
+ }
19
+ else if ('path' in event && event.path.length) {
20
+ return event.path[0];
21
+ }
22
+ return event.target;
23
+ }
24
+ catch (_a) {
25
+ return event.target;
26
+ }
27
+ }
28
+ function initMutationObserver(options, rootEl) {
29
+ var _a, _b;
30
+ const mutationBuffer = new MutationBuffer();
31
+ mutationBuffers.push(mutationBuffer);
32
+ mutationBuffer.init(options);
33
+ let mutationObserverCtor = window.MutationObserver ||
34
+ window.__rrMutationObserver;
35
+ const angularZoneSymbol = (_b = (_a = window === null || window === void 0 ? void 0 : window.Zone) === null || _a === void 0 ? void 0 : _a.__symbol__) === null || _b === void 0 ? void 0 : _b.call(_a, 'MutationObserver');
36
+ if (angularZoneSymbol &&
37
+ window[angularZoneSymbol]) {
38
+ mutationObserverCtor = window[angularZoneSymbol];
39
+ }
40
+ const observer = new mutationObserverCtor(mutationBuffer.processMutations.bind(mutationBuffer));
41
+ observer.observe(rootEl, {
42
+ attributes: true,
43
+ attributeOldValue: true,
44
+ characterData: true,
45
+ characterDataOldValue: true,
46
+ childList: true,
47
+ subtree: true,
48
+ });
49
+ return observer;
50
+ }
51
+ function initMoveObserver({ mousemoveCb, sampling, doc, mirror, }) {
52
+ if (sampling.mousemove === false) {
53
+ return () => { };
54
+ }
55
+ const threshold = typeof sampling.mousemove === 'number' ? sampling.mousemove : 50;
56
+ const callbackThreshold = typeof sampling.mousemoveCallback === 'number'
57
+ ? sampling.mousemoveCallback
58
+ : 500;
59
+ let positions = [];
60
+ let timeBaseline;
61
+ const wrappedCb = throttle((source) => {
62
+ const totalOffset = Date.now() - timeBaseline;
63
+ mousemoveCb(positions.map((p) => {
64
+ p.timeOffset -= totalOffset;
65
+ return p;
66
+ }), source);
67
+ positions = [];
68
+ timeBaseline = null;
69
+ }, callbackThreshold);
70
+ const updatePosition = throttle((evt) => {
71
+ const target = getEventTarget(evt);
72
+ const { clientX, clientY } = isTouchEvent(evt)
73
+ ? evt.changedTouches[0]
74
+ : evt;
75
+ if (!timeBaseline) {
76
+ timeBaseline = Date.now();
77
+ }
78
+ positions.push({
79
+ x: clientX,
80
+ y: clientY,
81
+ id: mirror.getId(target),
82
+ timeOffset: Date.now() - timeBaseline,
83
+ });
84
+ wrappedCb(typeof DragEvent !== 'undefined' && evt instanceof DragEvent
85
+ ? IncrementalSource.Drag
86
+ : evt instanceof MouseEvent
87
+ ? IncrementalSource.MouseMove
88
+ : IncrementalSource.TouchMove);
89
+ }, threshold, {
90
+ trailing: false,
91
+ });
92
+ const handlers = [
93
+ on('mousemove', updatePosition, doc),
94
+ on('touchmove', updatePosition, doc),
95
+ on('drag', updatePosition, doc),
96
+ ];
97
+ return () => {
98
+ handlers.forEach((h) => h());
99
+ };
100
+ }
101
+ function initMouseInteractionObserver({ mouseInteractionCb, doc, mirror, blockClass, sampling, }) {
102
+ if (sampling.mouseInteraction === false) {
103
+ return () => { };
104
+ }
105
+ const disableMap = sampling.mouseInteraction === true ||
106
+ sampling.mouseInteraction === undefined
107
+ ? {}
108
+ : sampling.mouseInteraction;
109
+ const handlers = [];
110
+ const getHandler = (eventKey) => {
111
+ return (event) => {
112
+ const target = getEventTarget(event);
113
+ if (isBlocked(target, blockClass) ||
114
+ isCanvasNode(target)) {
115
+ return;
116
+ }
117
+ const e = isTouchEvent(event) ? event.changedTouches[0] : event;
118
+ if (!e) {
119
+ return;
120
+ }
121
+ const id = mirror.getId(target);
122
+ const { clientX, clientY } = e;
123
+ mouseInteractionCb({
124
+ type: MouseInteractions[eventKey],
125
+ id,
126
+ x: clientX,
127
+ y: clientY,
128
+ });
129
+ };
130
+ };
131
+ Object.keys(MouseInteractions)
132
+ .filter((key) => Number.isNaN(Number(key)) &&
133
+ !key.endsWith('_Departed') &&
134
+ disableMap[key] !== false)
135
+ .forEach((eventKey) => {
136
+ const eventName = eventKey.toLowerCase();
137
+ const handler = getHandler(eventKey);
138
+ handlers.push(on(eventName, handler, doc));
139
+ });
140
+ return () => {
141
+ handlers.forEach((h) => h());
142
+ };
143
+ }
144
+ function initScrollObserver({ scrollCb, doc, mirror, blockClass, sampling, }) {
145
+ const updatePosition = throttle((evt) => {
146
+ const target = getEventTarget(evt);
147
+ if (!target || isBlocked(target, blockClass)) {
148
+ return;
149
+ }
150
+ const id = mirror.getId(target);
151
+ if (target === doc) {
152
+ const scrollEl = (doc.scrollingElement || doc.documentElement);
153
+ scrollCb({
154
+ id,
155
+ x: scrollEl.scrollLeft,
156
+ y: scrollEl.scrollTop,
157
+ });
158
+ }
159
+ else {
160
+ scrollCb({
161
+ id,
162
+ x: target.scrollLeft,
163
+ y: target.scrollTop,
164
+ });
165
+ }
166
+ }, sampling.scroll || 100);
167
+ return on('scroll', updatePosition, doc);
168
+ }
169
+ function initViewportResizeObserver({ viewportResizeCb, }) {
170
+ let lastH = -1;
171
+ let lastW = -1;
172
+ const updateDimension = throttle(() => {
173
+ const height = getWindowHeight();
174
+ const width = getWindowWidth();
175
+ if (lastH !== height || lastW !== width) {
176
+ viewportResizeCb({
177
+ width: Number(width),
178
+ height: Number(height),
179
+ });
180
+ lastH = height;
181
+ lastW = width;
182
+ }
183
+ }, 200);
184
+ return on('resize', updateDimension, window);
185
+ }
186
+ function wrapEventWithUserTriggeredFlag(v, enable) {
187
+ const value = Object.assign({}, v);
188
+ if (!enable)
189
+ delete value.userTriggered;
190
+ return value;
191
+ }
192
+ const INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];
193
+ const lastInputValueMap = new WeakMap();
194
+ function initInputObserver({ inputCb, doc, mirror, blockClass, ignoreClass, maskInputOptions, maskInputFn, sampling, userTriggeredOnInput, }) {
195
+ function eventHandler(event) {
196
+ let target = getEventTarget(event);
197
+ const userTriggered = event.isTrusted;
198
+ if (target && target.tagName === 'OPTION')
199
+ target = target.parentElement;
200
+ if (!target ||
201
+ !target.tagName ||
202
+ INPUT_TAGS.indexOf(target.tagName) < 0 ||
203
+ isBlocked(target, blockClass)) {
204
+ return;
205
+ }
206
+ const type = target.type;
207
+ if (target.classList.contains(ignoreClass)) {
208
+ return;
209
+ }
210
+ let text = target.value;
211
+ let isChecked = false;
212
+ if (type === 'radio' || type === 'checkbox') {
213
+ isChecked = target.checked;
214
+ }
215
+ else if (maskInputOptions[target.tagName.toLowerCase()] ||
216
+ maskInputOptions[type]) {
217
+ text = maskInputValue({
218
+ maskInputOptions,
219
+ tagName: target.tagName,
220
+ type,
221
+ value: text,
222
+ maskInputFn,
223
+ });
224
+ }
225
+ cbWithDedup(target, wrapEventWithUserTriggeredFlag({ text, isChecked, userTriggered }, userTriggeredOnInput));
226
+ const name = target.name;
227
+ if (type === 'radio' && name && isChecked) {
228
+ doc
229
+ .querySelectorAll(`input[type="radio"][name="${name}"]`)
230
+ .forEach((el) => {
231
+ if (el !== target) {
232
+ cbWithDedup(el, wrapEventWithUserTriggeredFlag({
233
+ text: el.value,
234
+ isChecked: !isChecked,
235
+ userTriggered: false,
236
+ }, userTriggeredOnInput));
237
+ }
238
+ });
239
+ }
240
+ }
241
+ function cbWithDedup(target, v) {
242
+ const lastInputValue = lastInputValueMap.get(target);
243
+ if (!lastInputValue ||
244
+ lastInputValue.text !== v.text ||
245
+ lastInputValue.isChecked !== v.isChecked) {
246
+ lastInputValueMap.set(target, v);
247
+ const id = mirror.getId(target);
248
+ inputCb(Object.assign(Object.assign({}, v), { id }));
249
+ }
250
+ }
251
+ const events = sampling.input === 'last' ? ['change'] : ['input', 'change'];
252
+ const handlers = events.map((eventName) => on(eventName, eventHandler, doc));
253
+ const propertyDescriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value');
254
+ const hookProperties = [
255
+ [HTMLInputElement.prototype, 'value'],
256
+ [HTMLInputElement.prototype, 'checked'],
257
+ [HTMLSelectElement.prototype, 'value'],
258
+ [HTMLTextAreaElement.prototype, 'value'],
259
+ [HTMLSelectElement.prototype, 'selectedIndex'],
260
+ [HTMLOptionElement.prototype, 'selected'],
261
+ ];
262
+ if (propertyDescriptor && propertyDescriptor.set) {
263
+ handlers.push(...hookProperties.map((p) => hookSetter(p[0], p[1], {
264
+ set() {
265
+ eventHandler({ target: this });
266
+ },
267
+ })));
268
+ }
269
+ return () => {
270
+ handlers.forEach((h) => h());
271
+ };
272
+ }
273
+ function getNestedCSSRulePositions(rule) {
274
+ const positions = [];
275
+ function recurse(childRule, pos) {
276
+ if ((isCSSGroupingRuleSupported &&
277
+ childRule.parentRule instanceof CSSGroupingRule) ||
278
+ (isCSSMediaRuleSupported &&
279
+ childRule.parentRule instanceof CSSMediaRule) ||
280
+ (isCSSSupportsRuleSupported &&
281
+ childRule.parentRule instanceof CSSSupportsRule) ||
282
+ (isCSSConditionRuleSupported &&
283
+ childRule.parentRule instanceof CSSConditionRule)) {
284
+ const rules = Array.from(childRule.parentRule.cssRules);
285
+ const index = rules.indexOf(childRule);
286
+ pos.unshift(index);
287
+ }
288
+ else {
289
+ const rules = Array.from(childRule.parentStyleSheet.cssRules);
290
+ const index = rules.indexOf(childRule);
291
+ pos.unshift(index);
292
+ }
293
+ return pos;
294
+ }
295
+ return recurse(rule, positions);
296
+ }
297
+ function initStyleSheetObserver({ styleSheetRuleCb, mirror }, { win }) {
298
+ const insertRule = win.CSSStyleSheet.prototype.insertRule;
299
+ win.CSSStyleSheet.prototype.insertRule = function (rule, index) {
300
+ const id = mirror.getId(this.ownerNode);
301
+ if (id !== -1) {
302
+ styleSheetRuleCb({
303
+ id,
304
+ adds: [{ rule, index }],
305
+ });
306
+ }
307
+ return insertRule.apply(this, arguments);
308
+ };
309
+ const deleteRule = win.CSSStyleSheet.prototype.deleteRule;
310
+ win.CSSStyleSheet.prototype.deleteRule = function (index) {
311
+ const id = mirror.getId(this.ownerNode);
312
+ if (id !== -1) {
313
+ styleSheetRuleCb({
314
+ id,
315
+ removes: [{ index }],
316
+ });
317
+ }
318
+ return deleteRule.apply(this, arguments);
319
+ };
320
+ const supportedNestedCSSRuleTypes = {};
321
+ if (isCSSGroupingRuleSupported) {
322
+ supportedNestedCSSRuleTypes.CSSGroupingRule = win.CSSGroupingRule;
323
+ }
324
+ else {
325
+ if (isCSSMediaRuleSupported) {
326
+ supportedNestedCSSRuleTypes.CSSMediaRule = win.CSSMediaRule;
327
+ }
328
+ if (isCSSConditionRuleSupported) {
329
+ supportedNestedCSSRuleTypes.CSSConditionRule = win.CSSConditionRule;
330
+ }
331
+ if (isCSSSupportsRuleSupported) {
332
+ supportedNestedCSSRuleTypes.CSSSupportsRule = win.CSSSupportsRule;
333
+ }
334
+ }
335
+ const unmodifiedFunctions = {};
336
+ Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
337
+ unmodifiedFunctions[typeKey] = {
338
+ insertRule: (type).prototype.insertRule,
339
+ deleteRule: (type).prototype.deleteRule,
340
+ };
341
+ type.prototype.insertRule = function (rule, index) {
342
+ const id = mirror.getId(this.parentStyleSheet.ownerNode);
343
+ if (id !== -1) {
344
+ styleSheetRuleCb({
345
+ id,
346
+ adds: [
347
+ {
348
+ rule,
349
+ index: [
350
+ ...getNestedCSSRulePositions(this),
351
+ index || 0,
352
+ ],
353
+ },
354
+ ],
355
+ });
356
+ }
357
+ return unmodifiedFunctions[typeKey].insertRule.apply(this, arguments);
358
+ };
359
+ type.prototype.deleteRule = function (index) {
360
+ const id = mirror.getId(this.parentStyleSheet.ownerNode);
361
+ if (id !== -1) {
362
+ styleSheetRuleCb({
363
+ id,
364
+ removes: [{ index: [...getNestedCSSRulePositions(this), index] }],
365
+ });
366
+ }
367
+ return unmodifiedFunctions[typeKey].deleteRule.apply(this, arguments);
368
+ };
369
+ });
370
+ return () => {
371
+ win.CSSStyleSheet.prototype.insertRule = insertRule;
372
+ win.CSSStyleSheet.prototype.deleteRule = deleteRule;
373
+ Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
374
+ type.prototype.insertRule = unmodifiedFunctions[typeKey].insertRule;
375
+ type.prototype.deleteRule = unmodifiedFunctions[typeKey].deleteRule;
376
+ });
377
+ };
378
+ }
379
+ function initStyleDeclarationObserver({ styleDeclarationCb, mirror }, { win }) {
380
+ const setProperty = win.CSSStyleDeclaration.prototype.setProperty;
381
+ win.CSSStyleDeclaration.prototype.setProperty = function (property, value, priority) {
382
+ var _a, _b;
383
+ const id = mirror.getId((_b = (_a = this.parentRule) === null || _a === void 0 ? void 0 : _a.parentStyleSheet) === null || _b === void 0 ? void 0 : _b.ownerNode);
384
+ if (id !== -1) {
385
+ styleDeclarationCb({
386
+ id,
387
+ set: {
388
+ property,
389
+ value,
390
+ priority,
391
+ },
392
+ index: getNestedCSSRulePositions(this.parentRule),
393
+ });
394
+ }
395
+ return setProperty.apply(this, arguments);
396
+ };
397
+ const removeProperty = win.CSSStyleDeclaration.prototype.removeProperty;
398
+ win.CSSStyleDeclaration.prototype.removeProperty = function (property) {
399
+ var _a, _b;
400
+ const id = mirror.getId((_b = (_a = this.parentRule) === null || _a === void 0 ? void 0 : _a.parentStyleSheet) === null || _b === void 0 ? void 0 : _b.ownerNode);
401
+ if (id !== -1) {
402
+ styleDeclarationCb({
403
+ id,
404
+ remove: {
405
+ property,
406
+ },
407
+ index: getNestedCSSRulePositions(this.parentRule),
408
+ });
409
+ }
410
+ return removeProperty.apply(this, arguments);
411
+ };
412
+ return () => {
413
+ win.CSSStyleDeclaration.prototype.setProperty = setProperty;
414
+ win.CSSStyleDeclaration.prototype.removeProperty = removeProperty;
415
+ };
416
+ }
417
+ function initMediaInteractionObserver({ mediaInteractionCb, blockClass, mirror, sampling, }) {
418
+ const handler = (type) => throttle((event) => {
419
+ const target = getEventTarget(event);
420
+ if (!target || isBlocked(target, blockClass)) {
421
+ return;
422
+ }
423
+ const { currentTime, volume, muted } = target;
424
+ mediaInteractionCb({
425
+ type,
426
+ id: mirror.getId(target),
427
+ currentTime,
428
+ volume,
429
+ muted,
430
+ });
431
+ }, sampling.media || 500);
432
+ const handlers = [
433
+ on('play', handler(0)),
434
+ on('pause', handler(1)),
435
+ on('seeked', handler(2)),
436
+ on('volumechange', handler(3)),
437
+ ];
438
+ return () => {
439
+ handlers.forEach((h) => h());
440
+ };
441
+ }
442
+ function initFontObserver({ fontCb, doc }) {
443
+ const win = doc.defaultView;
444
+ if (!win) {
445
+ return () => { };
446
+ }
447
+ const handlers = [];
448
+ const fontMap = new WeakMap();
449
+ const originalFontFace = win.FontFace;
450
+ win.FontFace = function FontFace(family, source, descriptors) {
451
+ const fontFace = new originalFontFace(family, source, descriptors);
452
+ fontMap.set(fontFace, {
453
+ family,
454
+ buffer: typeof source !== 'string',
455
+ descriptors,
456
+ fontSource: typeof source === 'string'
457
+ ? source
458
+ :
459
+ JSON.stringify(Array.from(new Uint8Array(source))),
460
+ });
461
+ return fontFace;
462
+ };
463
+ const restoreHandler = patch(doc.fonts, 'add', function (original) {
464
+ return function (fontFace) {
465
+ setTimeout(() => {
466
+ const p = fontMap.get(fontFace);
467
+ if (p) {
468
+ fontCb(p);
469
+ fontMap.delete(fontFace);
470
+ }
471
+ }, 0);
472
+ return original.apply(this, [fontFace]);
473
+ };
474
+ });
475
+ handlers.push(() => {
476
+ win.FontFace = originalFontFace;
477
+ });
478
+ handlers.push(restoreHandler);
479
+ return () => {
480
+ handlers.forEach((h) => h());
481
+ };
482
+ }
483
+ function mergeHooks(o, hooks) {
484
+ const { mutationCb, mousemoveCb, mouseInteractionCb, scrollCb, viewportResizeCb, inputCb, mediaInteractionCb, styleSheetRuleCb, styleDeclarationCb, canvasMutationCb, fontCb, } = o;
485
+ o.mutationCb = (...p) => {
486
+ if (hooks.mutation) {
487
+ hooks.mutation(...p);
488
+ }
489
+ mutationCb(...p);
490
+ };
491
+ o.mousemoveCb = (...p) => {
492
+ if (hooks.mousemove) {
493
+ hooks.mousemove(...p);
494
+ }
495
+ mousemoveCb(...p);
496
+ };
497
+ o.mouseInteractionCb = (...p) => {
498
+ if (hooks.mouseInteraction) {
499
+ hooks.mouseInteraction(...p);
500
+ }
501
+ mouseInteractionCb(...p);
502
+ };
503
+ o.scrollCb = (...p) => {
504
+ if (hooks.scroll) {
505
+ hooks.scroll(...p);
506
+ }
507
+ scrollCb(...p);
508
+ };
509
+ o.viewportResizeCb = (...p) => {
510
+ if (hooks.viewportResize) {
511
+ hooks.viewportResize(...p);
512
+ }
513
+ viewportResizeCb(...p);
514
+ };
515
+ o.inputCb = (...p) => {
516
+ if (hooks.input) {
517
+ hooks.input(...p);
518
+ }
519
+ inputCb(...p);
520
+ };
521
+ o.mediaInteractionCb = (...p) => {
522
+ if (hooks.mediaInteaction) {
523
+ hooks.mediaInteaction(...p);
524
+ }
525
+ mediaInteractionCb(...p);
526
+ };
527
+ o.styleSheetRuleCb = (...p) => {
528
+ if (hooks.styleSheetRule) {
529
+ hooks.styleSheetRule(...p);
530
+ }
531
+ styleSheetRuleCb(...p);
532
+ };
533
+ o.styleDeclarationCb = (...p) => {
534
+ if (hooks.styleDeclaration) {
535
+ hooks.styleDeclaration(...p);
536
+ }
537
+ styleDeclarationCb(...p);
538
+ };
539
+ o.canvasMutationCb = (...p) => {
540
+ if (hooks.canvasMutation) {
541
+ hooks.canvasMutation(...p);
542
+ }
543
+ canvasMutationCb(...p);
544
+ };
545
+ o.fontCb = (...p) => {
546
+ if (hooks.font) {
547
+ hooks.font(...p);
548
+ }
549
+ fontCb(...p);
550
+ };
551
+ }
552
+ function initObservers(o, hooks = {}) {
553
+ const currentWindow = o.doc.defaultView;
554
+ if (!currentWindow) {
555
+ return () => { };
556
+ }
557
+ mergeHooks(o, hooks);
558
+ const mutationObserver = initMutationObserver(o, o.doc);
559
+ const mousemoveHandler = initMoveObserver(o);
560
+ const mouseInteractionHandler = initMouseInteractionObserver(o);
561
+ const scrollHandler = initScrollObserver(o);
562
+ const viewportResizeHandler = initViewportResizeObserver(o);
563
+ const inputHandler = initInputObserver(o);
564
+ const mediaInteractionHandler = initMediaInteractionObserver(o);
565
+ const styleSheetObserver = initStyleSheetObserver(o, { win: currentWindow });
566
+ const styleDeclarationObserver = initStyleDeclarationObserver(o, {
567
+ win: currentWindow,
568
+ });
569
+ const fontObserver = o.collectFonts ? initFontObserver(o) : () => { };
570
+ const pluginHandlers = [];
571
+ for (const plugin of o.plugins) {
572
+ pluginHandlers.push(plugin.observer(plugin.callback, currentWindow, plugin.options));
573
+ }
574
+ return () => {
575
+ mutationBuffers.forEach((b) => b.reset());
576
+ mutationObserver.disconnect();
577
+ mousemoveHandler();
578
+ mouseInteractionHandler();
579
+ scrollHandler();
580
+ viewportResizeHandler();
581
+ inputHandler();
582
+ mediaInteractionHandler();
583
+ styleSheetObserver();
584
+ styleDeclarationObserver();
585
+ fontObserver();
586
+ pluginHandlers.forEach((h) => h());
587
+ };
588
+ }
589
+
590
+ export { INPUT_TAGS, initMutationObserver, initObservers, initScrollObserver, mutationBuffers };
@@ -0,0 +1,49 @@
1
+ import { CanvasContext } from '../../../types.js';
2
+ import { patch, isBlocked, hookSetter } from '../../../utils.js';
3
+ import { serializeArgs } from './serialize-args.js';
4
+
5
+ function initCanvas2DMutationObserver(cb, win, blockClass, mirror) {
6
+ const handlers = [];
7
+ const props2D = Object.getOwnPropertyNames(win.CanvasRenderingContext2D.prototype);
8
+ for (const prop of props2D) {
9
+ try {
10
+ if (typeof win.CanvasRenderingContext2D.prototype[prop] !== 'function') {
11
+ continue;
12
+ }
13
+ const restoreHandler = patch(win.CanvasRenderingContext2D.prototype, prop, function (original) {
14
+ return function (...args) {
15
+ if (!isBlocked(this.canvas, blockClass)) {
16
+ setTimeout(() => {
17
+ const recordArgs = serializeArgs([...args], win, this);
18
+ cb(this.canvas, {
19
+ type: CanvasContext['2D'],
20
+ property: prop,
21
+ args: recordArgs,
22
+ });
23
+ }, 0);
24
+ }
25
+ return original.apply(this, args);
26
+ };
27
+ });
28
+ handlers.push(restoreHandler);
29
+ }
30
+ catch (_a) {
31
+ const hookHandler = hookSetter(win.CanvasRenderingContext2D.prototype, prop, {
32
+ set(v) {
33
+ cb(this.canvas, {
34
+ type: CanvasContext['2D'],
35
+ property: prop,
36
+ args: [v],
37
+ setter: true,
38
+ });
39
+ },
40
+ });
41
+ handlers.push(hookHandler);
42
+ }
43
+ }
44
+ return () => {
45
+ handlers.forEach((h) => h());
46
+ };
47
+ }
48
+
49
+ export { initCanvas2DMutationObserver as default };