@highlight-run/rrweb 2.0.4 → 2.0.7

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 (56) hide show
  1. package/dist/plugins/console-record.js +12 -454
  2. package/dist/plugins/console-record.min.js +1 -1
  3. package/dist/plugins/console-record.min.js.map +1 -1
  4. package/dist/plugins/console-replay.js +4 -164
  5. package/dist/plugins/console-replay.min.js.map +1 -1
  6. package/dist/plugins/sequential-id-record.js +1 -30
  7. package/dist/plugins/sequential-id-replay.js +1 -33
  8. package/dist/record/rrweb-record-pack.js +3 -664
  9. package/dist/record/rrweb-record-pack.min.js.map +1 -1
  10. package/dist/record/rrweb-record.js +4 -3202
  11. package/dist/record/rrweb-record.min.js +3 -3
  12. package/dist/record/rrweb-record.min.js.map +1 -1
  13. package/dist/replay/rrweb-replay-unpack.css +1 -0
  14. package/dist/replay/rrweb-replay-unpack.js +5 -4914
  15. package/dist/replay/rrweb-replay-unpack.min.css +2 -0
  16. package/dist/replay/rrweb-replay-unpack.min.css.map +1 -0
  17. package/dist/replay/rrweb-replay-unpack.min.js +4 -4
  18. package/dist/replay/rrweb-replay-unpack.min.js.map +1 -1
  19. package/dist/replay/rrweb-replay.css +1 -0
  20. package/dist/replay/rrweb-replay.js +5 -4506
  21. package/dist/replay/rrweb-replay.min.css +2 -0
  22. package/dist/replay/rrweb-replay.min.css.map +1 -0
  23. package/dist/replay/rrweb-replay.min.js +3 -3
  24. package/dist/replay/rrweb-replay.min.js.map +1 -1
  25. package/dist/rrweb-all.css +1 -0
  26. package/dist/rrweb-all.js +16 -8877
  27. package/dist/rrweb-all.min.css +2 -0
  28. package/dist/rrweb-all.min.css.map +1 -0
  29. package/dist/rrweb-all.min.js +12 -12
  30. package/dist/rrweb-all.min.js.map +1 -1
  31. package/dist/rrweb.css +1 -0
  32. package/dist/rrweb.js +6 -7546
  33. package/dist/rrweb.min.css +2 -0
  34. package/dist/rrweb.min.css.map +1 -0
  35. package/dist/rrweb.min.js +5 -5
  36. package/dist/rrweb.min.js.map +1 -1
  37. package/es/rrweb/all.css +1 -0
  38. package/es/rrweb/packages/rrweb/src/record/index.js +5 -2
  39. package/es/rrweb/packages/rrweb/src/record/mutation.js +23 -11
  40. package/es/rrweb/packages/rrweb/src/record/observer.js +6 -6
  41. package/es/rrweb/packages/rrweb/src/record/observers/canvas/2d.js +1 -1
  42. package/es/rrweb/packages/rrweb/src/record/observers/canvas/canvas.js +2 -2
  43. package/es/rrweb/packages/rrweb/src/record/observers/canvas/webgl.js +1 -2
  44. package/es/rrweb/packages/rrweb/src/utils.js +16 -23
  45. package/es/rrweb/packages/rrweb-snapshot/es/rrweb-snapshot.js +283 -243
  46. package/lib/record/rrweb-record.js +333 -286
  47. package/lib/replay/rrweb-replay-unpack.css +1 -0
  48. package/lib/replay/rrweb-replay-unpack.js +1 -1
  49. package/lib/replay/rrweb-replay.css +1 -0
  50. package/lib/replay/rrweb-replay.js +1 -1
  51. package/lib/rrweb-all.css +1 -0
  52. package/lib/rrweb-all.js +334 -287
  53. package/lib/rrweb.css +1 -0
  54. package/lib/rrweb.js +334 -287
  55. package/package.json +4 -4
  56. package/typings/utils.d.ts +1 -1
@@ -16,7 +16,7 @@ function isElement(n) {
16
16
  function isShadowRoot(n) {
17
17
  var _a;
18
18
  var host = (_a = n) === null || _a === void 0 ? void 0 : _a.host;
19
- return Boolean(host && host.shadowRoot && host.shadowRoot === n);
19
+ return Boolean((host === null || host === void 0 ? void 0 : host.shadowRoot) === n);
20
20
  }
21
21
  var Mirror = (function () {
22
22
  function Mirror() {
@@ -316,7 +316,7 @@ function _isBlockedElement(element, blockClass, blockSelector) {
316
316
  }
317
317
  }
318
318
  else {
319
- for (var eIndex = 0; eIndex < element.classList.length; eIndex++) {
319
+ for (var eIndex = element.classList.length; eIndex--;) {
320
320
  var className = element.classList[eIndex];
321
321
  if (blockClass.test(className)) {
322
322
  return true;
@@ -328,35 +328,47 @@ function _isBlockedElement(element, blockClass, blockSelector) {
328
328
  }
329
329
  return false;
330
330
  }
331
- function needMaskingText(node, maskTextClass, maskTextSelector) {
332
- if (!node) {
331
+ function classMatchesRegex(node, regex, checkAncestors) {
332
+ if (!node)
333
333
  return false;
334
+ if (node.nodeType !== node.ELEMENT_NODE) {
335
+ if (!checkAncestors)
336
+ return false;
337
+ return classMatchesRegex(node.parentNode, regex, checkAncestors);
334
338
  }
335
- if (node.nodeType === node.ELEMENT_NODE) {
336
- if (typeof maskTextClass === 'string') {
337
- if (node.classList.contains(maskTextClass)) {
338
- return true;
339
- }
340
- }
341
- else {
342
- for (var eIndex = 0; eIndex < node.classList.length; eIndex++) {
343
- var className = node.classList[eIndex];
344
- if (maskTextClass.test(className)) {
345
- return true;
346
- }
347
- }
348
- }
349
- if (maskTextSelector) {
350
- if (node.matches(maskTextSelector)) {
351
- return true;
352
- }
339
+ for (var eIndex = node.classList.length; eIndex--;) {
340
+ var className = node.classList[eIndex];
341
+ if (regex.test(className)) {
342
+ return true;
353
343
  }
354
- return needMaskingText(node.parentNode, maskTextClass, maskTextSelector);
355
344
  }
356
- if (node.nodeType === node.TEXT_NODE) {
357
- return needMaskingText(node.parentNode, maskTextClass, maskTextSelector);
345
+ if (!checkAncestors)
346
+ return false;
347
+ return classMatchesRegex(node.parentNode, regex, checkAncestors);
348
+ }
349
+ function needMaskingText(node, maskTextClass, maskTextSelector) {
350
+ var el = node.nodeType === node.ELEMENT_NODE
351
+ ? node
352
+ : node.parentElement;
353
+ if (el === null)
354
+ return false;
355
+ if (typeof maskTextClass === 'string') {
356
+ if (el.classList.contains(maskTextClass))
357
+ return true;
358
+ if (el.closest("." + maskTextClass))
359
+ return true;
360
+ }
361
+ else {
362
+ if (classMatchesRegex(el, maskTextClass, true))
363
+ return true;
364
+ }
365
+ if (maskTextSelector) {
366
+ if (el.matches(maskTextSelector))
367
+ return true;
368
+ if (el.closest(maskTextSelector))
369
+ return true;
358
370
  }
359
- return needMaskingText(node.parentNode, maskTextClass, maskTextSelector);
371
+ return false;
360
372
  }
361
373
  function onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) {
362
374
  var win = iframeEl.contentWindow;
@@ -423,13 +435,8 @@ function onceStylesheetLoaded(link, listener, iframeLoadTimeout) {
423
435
  });
424
436
  }
425
437
  function serializeNode(n, options) {
426
- var _a;
427
- var doc = options.doc, mirror = options.mirror, blockClass = options.blockClass, blockSelector = options.blockSelector, maskTextClass = options.maskTextClass, maskTextSelector = options.maskTextSelector, inlineStylesheet = options.inlineStylesheet, _b = options.maskInputOptions, maskInputOptions = _b === void 0 ? {} : _b, maskTextFn = options.maskTextFn, maskInputFn = options.maskInputFn, _c = options.dataURLOptions, dataURLOptions = _c === void 0 ? {} : _c, inlineImages = options.inlineImages, recordCanvas = options.recordCanvas, keepIframeSrcFn = options.keepIframeSrcFn, enableStrictPrivacy = options.enableStrictPrivacy;
428
- var rootId;
429
- if (mirror.getMeta(doc)) {
430
- var docId = mirror.getId(doc);
431
- rootId = docId === 1 ? undefined : docId;
432
- }
438
+ var doc = options.doc, mirror = options.mirror, blockClass = options.blockClass, blockSelector = options.blockSelector, maskTextClass = options.maskTextClass, maskTextSelector = options.maskTextSelector, inlineStylesheet = options.inlineStylesheet, _a = options.maskInputOptions, maskInputOptions = _a === void 0 ? {} : _a, maskTextFn = options.maskTextFn, maskInputFn = options.maskInputFn, _b = options.dataURLOptions, dataURLOptions = _b === void 0 ? {} : _b, inlineImages = options.inlineImages, recordCanvas = options.recordCanvas, keepIframeSrcFn = options.keepIframeSrcFn, _c = options.newlyAddedElement, newlyAddedElement = _c === void 0 ? false : _c, enableStrictPrivacy = options.enableStrictPrivacy;
439
+ var rootId = getRootId(doc, mirror);
433
440
  switch (n.nodeType) {
434
441
  case n.DOCUMENT_NODE:
435
442
  if (n.compatMode !== 'CSS1Compat') {
@@ -456,203 +463,29 @@ function serializeNode(n, options) {
456
463
  rootId: rootId
457
464
  };
458
465
  case n.ELEMENT_NODE:
459
- var needBlock = _isBlockedElement(n, blockClass, blockSelector);
460
- var tagName = getValidTagName(n);
461
- var attributes_1 = {};
462
- var len = n.attributes.length;
463
- for (var i = 0; i < len; i++) {
464
- var attr = n.attributes[i];
465
- attributes_1[attr.name] = transformAttribute(doc, tagName, attr.name, attr.value);
466
- }
467
- if (tagName === 'link' && inlineStylesheet) {
468
- var stylesheet = Array.from(doc.styleSheets).find(function (s) {
469
- return s.href === n.href;
470
- });
471
- var cssText = null;
472
- if (stylesheet) {
473
- cssText = getCssRulesString(stylesheet);
474
- }
475
- if (cssText) {
476
- delete attributes_1.rel;
477
- delete attributes_1.href;
478
- attributes_1._cssText = absoluteToStylesheet(cssText, stylesheet.href);
479
- }
480
- }
481
- if (tagName === 'style' &&
482
- n.sheet &&
483
- !(n.innerText ||
484
- n.textContent ||
485
- '').trim().length) {
486
- var cssText = getCssRulesString(n.sheet);
487
- if (cssText) {
488
- attributes_1._cssText = absoluteToStylesheet(cssText, getHref());
489
- }
490
- }
491
- if (tagName === 'input' ||
492
- tagName === 'textarea' ||
493
- tagName === 'select') {
494
- var value = n.value;
495
- if (attributes_1.type !== 'radio' &&
496
- attributes_1.type !== 'checkbox' &&
497
- attributes_1.type !== 'submit' &&
498
- attributes_1.type !== 'button' &&
499
- value) {
500
- attributes_1.value = maskInputValue({
501
- type: attributes_1.type,
502
- tagName: tagName,
503
- value: value,
504
- maskInputOptions: maskInputOptions,
505
- maskInputFn: maskInputFn
506
- });
507
- }
508
- else if (n.checked) {
509
- attributes_1.checked = n.checked;
510
- }
511
- }
512
- if (tagName === 'option') {
513
- if (n.selected && !maskInputOptions['select']) {
514
- attributes_1.selected = true;
515
- }
516
- else {
517
- delete attributes_1.selected;
518
- }
519
- }
520
- if (tagName === 'canvas' && recordCanvas) {
521
- if (n.__context === '2d') {
522
- if (!is2DCanvasBlank(n)) {
523
- attributes_1.rr_dataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);
524
- }
525
- }
526
- else if (!('__context' in n)) {
527
- var canvasDataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);
528
- var blankCanvas = document.createElement('canvas');
529
- blankCanvas.width = n.width;
530
- blankCanvas.height = n.height;
531
- var blankCanvasDataURL = blankCanvas.toDataURL(dataURLOptions.type, dataURLOptions.quality);
532
- if (canvasDataURL !== blankCanvasDataURL) {
533
- attributes_1.rr_dataURL = canvasDataURL;
534
- }
535
- }
536
- }
537
- if (tagName === 'img' && inlineImages) {
538
- if (!canvasService) {
539
- canvasService = doc.createElement('canvas');
540
- canvasCtx = canvasService.getContext('2d');
541
- }
542
- var image_1 = n;
543
- var oldValue_1 = image_1.crossOrigin;
544
- image_1.crossOrigin = 'anonymous';
545
- var recordInlineImage = function () {
546
- try {
547
- canvasService.width = image_1.naturalWidth;
548
- canvasService.height = image_1.naturalHeight;
549
- canvasCtx.drawImage(image_1, 0, 0);
550
- attributes_1.rr_dataURL = canvasService.toDataURL(dataURLOptions.type, dataURLOptions.quality);
551
- }
552
- catch (err) {
553
- console.warn("Cannot inline img src=" + image_1.currentSrc + "! Error: " + err);
554
- }
555
- oldValue_1
556
- ? (attributes_1.crossOrigin = oldValue_1)
557
- : image_1.removeAttribute('crossorigin');
558
- };
559
- if (image_1.complete && image_1.naturalWidth !== 0)
560
- recordInlineImage();
561
- else
562
- image_1.onload = recordInlineImage;
563
- }
564
- if (tagName === 'audio' || tagName === 'video') {
565
- attributes_1.rr_mediaState = n.paused
566
- ? 'paused'
567
- : 'played';
568
- attributes_1.rr_mediaCurrentTime = n.currentTime;
569
- }
570
- if (n.scrollLeft) {
571
- attributes_1.rr_scrollLeft = n.scrollLeft;
572
- }
573
- if (n.scrollTop) {
574
- attributes_1.rr_scrollTop = n.scrollTop;
575
- }
576
- if (needBlock || (tagName === 'img' && enableStrictPrivacy)) {
577
- var _d = n.getBoundingClientRect(), width = _d.width, height = _d.height;
578
- attributes_1 = {
579
- "class": attributes_1["class"],
580
- rr_width: width + "px",
581
- rr_height: height + "px"
582
- };
583
- needBlock = true;
584
- }
585
- if (tagName === 'iframe' && !keepIframeSrcFn(attributes_1.src)) {
586
- if (!n.contentDocument) {
587
- attributes_1.rr_src = attributes_1.src;
588
- }
589
- delete attributes_1.src;
590
- }
591
- return {
592
- type: NodeType.Element,
593
- tagName: tagName,
594
- attributes: attributes_1,
595
- childNodes: [],
596
- isSVG: isSVGElement(n) || undefined,
597
- needBlock: needBlock,
466
+ return serializeElementNode(n, {
467
+ doc: doc,
468
+ blockClass: blockClass,
469
+ blockSelector: blockSelector,
470
+ inlineStylesheet: inlineStylesheet,
471
+ maskInputOptions: maskInputOptions,
472
+ maskInputFn: maskInputFn,
473
+ dataURLOptions: dataURLOptions,
474
+ inlineImages: inlineImages,
475
+ recordCanvas: recordCanvas,
476
+ keepIframeSrcFn: keepIframeSrcFn,
477
+ newlyAddedElement: newlyAddedElement,
478
+ enableStrictPrivacy: enableStrictPrivacy,
598
479
  rootId: rootId
599
- };
480
+ });
600
481
  case n.TEXT_NODE:
601
- var parentTagName = n.parentNode && n.parentNode.tagName;
602
- var textContent = n.textContent;
603
- var isStyle = parentTagName === 'STYLE' ? true : undefined;
604
- var isScript = parentTagName === 'SCRIPT' ? true : undefined;
605
- var textContentHandled = false;
606
- if (isStyle && textContent) {
607
- try {
608
- if (n.nextSibling || n.previousSibling) {
609
- }
610
- else if ((_a = n.parentNode.sheet) === null || _a === void 0 ? void 0 : _a.cssRules) {
611
- textContent = stringifyStyleSheet(n.parentNode.sheet);
612
- }
613
- }
614
- catch (err) {
615
- console.warn("Cannot get CSS styles from text's parentNode. Error: " + err, n);
616
- }
617
- textContent = absoluteToStylesheet(textContent, getHref());
618
- textContentHandled = true;
619
- }
620
- if (isScript) {
621
- textContent = 'SCRIPT_PLACEHOLDER';
622
- textContentHandled = true;
623
- }
624
- else if (parentTagName === 'NOSCRIPT') {
625
- textContent = '';
626
- textContentHandled = true;
627
- }
628
- if (!isStyle &&
629
- !isScript &&
630
- needMaskingText(n, maskTextClass, maskTextSelector) &&
631
- textContent) {
632
- textContent = maskTextFn
633
- ? maskTextFn(textContent)
634
- : textContent.replace(/[\S]/g, '*');
635
- }
636
- if (enableStrictPrivacy && !textContentHandled && parentTagName) {
637
- var IGNORE_TAG_NAMES = new Set([
638
- 'HEAD',
639
- 'TITLE',
640
- 'STYLE',
641
- 'SCRIPT',
642
- 'HTML',
643
- 'BODY',
644
- 'NOSCRIPT',
645
- ]);
646
- if (!IGNORE_TAG_NAMES.has(parentTagName) && textContent) {
647
- textContent = obfuscateText(textContent);
648
- }
649
- }
650
- return {
651
- type: NodeType.Text,
652
- textContent: textContent || '',
653
- isStyle: isStyle,
482
+ return serializeTextNode(n, {
483
+ maskTextClass: maskTextClass,
484
+ maskTextSelector: maskTextSelector,
485
+ maskTextFn: maskTextFn,
486
+ enableStrictPrivacy: enableStrictPrivacy,
654
487
  rootId: rootId
655
- };
488
+ });
656
489
  case n.CDATA_SECTION_NODE:
657
490
  return {
658
491
  type: NodeType.CDATA,
@@ -669,6 +502,213 @@ function serializeNode(n, options) {
669
502
  return false;
670
503
  }
671
504
  }
505
+ function getRootId(doc, mirror) {
506
+ if (!mirror.hasNode(doc))
507
+ return undefined;
508
+ var docId = mirror.getId(doc);
509
+ return docId === 1 ? undefined : docId;
510
+ }
511
+ function serializeTextNode(n, options) {
512
+ var _a;
513
+ var maskTextClass = options.maskTextClass, maskTextSelector = options.maskTextSelector, maskTextFn = options.maskTextFn, enableStrictPrivacy = options.enableStrictPrivacy, rootId = options.rootId;
514
+ var parentTagName = n.parentNode && n.parentNode.tagName;
515
+ var textContent = n.textContent;
516
+ var isStyle = parentTagName === 'STYLE' ? true : undefined;
517
+ var isScript = parentTagName === 'SCRIPT' ? true : undefined;
518
+ var textContentHandled = false;
519
+ if (isStyle && textContent) {
520
+ try {
521
+ if (n.nextSibling || n.previousSibling) {
522
+ }
523
+ else if ((_a = n.parentNode.sheet) === null || _a === void 0 ? void 0 : _a.cssRules) {
524
+ textContent = stringifyStyleSheet(n.parentNode.sheet);
525
+ }
526
+ }
527
+ catch (err) {
528
+ console.warn("Cannot get CSS styles from text's parentNode. Error: " + err, n);
529
+ }
530
+ textContent = absoluteToStylesheet(textContent, getHref());
531
+ textContentHandled = true;
532
+ }
533
+ if (isScript) {
534
+ textContent = 'SCRIPT_PLACEHOLDER';
535
+ textContentHandled = true;
536
+ }
537
+ else if (parentTagName === 'NOSCRIPT') {
538
+ textContent = '';
539
+ textContentHandled = true;
540
+ }
541
+ if (!isStyle &&
542
+ !isScript &&
543
+ textContent &&
544
+ needMaskingText(n, maskTextClass, maskTextSelector)) {
545
+ textContent = maskTextFn
546
+ ? maskTextFn(textContent)
547
+ : textContent.replace(/[\S]/g, '*');
548
+ }
549
+ if (enableStrictPrivacy && !textContentHandled && parentTagName) {
550
+ var IGNORE_TAG_NAMES = new Set([
551
+ 'HEAD',
552
+ 'TITLE',
553
+ 'STYLE',
554
+ 'SCRIPT',
555
+ 'HTML',
556
+ 'BODY',
557
+ 'NOSCRIPT',
558
+ ]);
559
+ if (!IGNORE_TAG_NAMES.has(parentTagName) && textContent) {
560
+ textContent = obfuscateText(textContent);
561
+ }
562
+ }
563
+ return {
564
+ type: NodeType.Text,
565
+ textContent: textContent || '',
566
+ isStyle: isStyle,
567
+ rootId: rootId
568
+ };
569
+ }
570
+ function serializeElementNode(n, options) {
571
+ var doc = options.doc, blockClass = options.blockClass, blockSelector = options.blockSelector, inlineStylesheet = options.inlineStylesheet, _a = options.maskInputOptions, maskInputOptions = _a === void 0 ? {} : _a, maskInputFn = options.maskInputFn, _b = options.dataURLOptions, dataURLOptions = _b === void 0 ? {} : _b, inlineImages = options.inlineImages, recordCanvas = options.recordCanvas, keepIframeSrcFn = options.keepIframeSrcFn, _c = options.newlyAddedElement, newlyAddedElement = _c === void 0 ? false : _c, enableStrictPrivacy = options.enableStrictPrivacy, rootId = options.rootId;
572
+ var needBlock = _isBlockedElement(n, blockClass, blockSelector);
573
+ var tagName = getValidTagName(n);
574
+ var attributes = {};
575
+ var len = n.attributes.length;
576
+ for (var i = 0; i < len; i++) {
577
+ var attr = n.attributes[i];
578
+ attributes[attr.name] = transformAttribute(doc, tagName, attr.name, attr.value);
579
+ }
580
+ if (tagName === 'link' && inlineStylesheet) {
581
+ var stylesheet = Array.from(doc.styleSheets).find(function (s) {
582
+ return s.href === n.href;
583
+ });
584
+ var cssText = null;
585
+ if (stylesheet) {
586
+ cssText = getCssRulesString(stylesheet);
587
+ }
588
+ if (cssText) {
589
+ delete attributes.rel;
590
+ delete attributes.href;
591
+ attributes._cssText = absoluteToStylesheet(cssText, stylesheet.href);
592
+ }
593
+ }
594
+ if (tagName === 'style' &&
595
+ n.sheet &&
596
+ !(n.innerText || n.textContent || '').trim().length) {
597
+ var cssText = getCssRulesString(n.sheet);
598
+ if (cssText) {
599
+ attributes._cssText = absoluteToStylesheet(cssText, getHref());
600
+ }
601
+ }
602
+ if (tagName === 'input' || tagName === 'textarea' || tagName === 'select') {
603
+ var value = n.value;
604
+ if (attributes.type !== 'radio' &&
605
+ attributes.type !== 'checkbox' &&
606
+ attributes.type !== 'submit' &&
607
+ attributes.type !== 'button' &&
608
+ value) {
609
+ attributes.value = maskInputValue({
610
+ type: attributes.type,
611
+ tagName: tagName,
612
+ value: value,
613
+ maskInputOptions: maskInputOptions,
614
+ maskInputFn: maskInputFn
615
+ });
616
+ }
617
+ else if (n.checked) {
618
+ attributes.checked = n.checked;
619
+ }
620
+ }
621
+ if (tagName === 'option') {
622
+ if (n.selected && !maskInputOptions['select']) {
623
+ attributes.selected = true;
624
+ }
625
+ else {
626
+ delete attributes.selected;
627
+ }
628
+ }
629
+ if (tagName === 'canvas' && recordCanvas) {
630
+ if (n.__context === '2d') {
631
+ if (!is2DCanvasBlank(n)) {
632
+ attributes.rr_dataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);
633
+ }
634
+ }
635
+ else if (!('__context' in n)) {
636
+ var canvasDataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);
637
+ var blankCanvas = document.createElement('canvas');
638
+ blankCanvas.width = n.width;
639
+ blankCanvas.height = n.height;
640
+ var blankCanvasDataURL = blankCanvas.toDataURL(dataURLOptions.type, dataURLOptions.quality);
641
+ if (canvasDataURL !== blankCanvasDataURL) {
642
+ attributes.rr_dataURL = canvasDataURL;
643
+ }
644
+ }
645
+ }
646
+ if (tagName === 'img' && inlineImages) {
647
+ if (!canvasService) {
648
+ canvasService = doc.createElement('canvas');
649
+ canvasCtx = canvasService.getContext('2d');
650
+ }
651
+ var image_1 = n;
652
+ var oldValue_1 = image_1.crossOrigin;
653
+ image_1.crossOrigin = 'anonymous';
654
+ var recordInlineImage = function () {
655
+ try {
656
+ canvasService.width = image_1.naturalWidth;
657
+ canvasService.height = image_1.naturalHeight;
658
+ canvasCtx.drawImage(image_1, 0, 0);
659
+ attributes.rr_dataURL = canvasService.toDataURL(dataURLOptions.type, dataURLOptions.quality);
660
+ }
661
+ catch (err) {
662
+ console.warn("Cannot inline img src=" + image_1.currentSrc + "! Error: " + err);
663
+ }
664
+ oldValue_1
665
+ ? (attributes.crossOrigin = oldValue_1)
666
+ : image_1.removeAttribute('crossorigin');
667
+ };
668
+ if (image_1.complete && image_1.naturalWidth !== 0)
669
+ recordInlineImage();
670
+ else
671
+ image_1.onload = recordInlineImage;
672
+ }
673
+ if (tagName === 'audio' || tagName === 'video') {
674
+ attributes.rr_mediaState = n.paused
675
+ ? 'paused'
676
+ : 'played';
677
+ attributes.rr_mediaCurrentTime = n.currentTime;
678
+ }
679
+ if (!newlyAddedElement) {
680
+ if (n.scrollLeft) {
681
+ attributes.rr_scrollLeft = n.scrollLeft;
682
+ }
683
+ if (n.scrollTop) {
684
+ attributes.rr_scrollTop = n.scrollTop;
685
+ }
686
+ }
687
+ if (needBlock || (tagName === 'img' && enableStrictPrivacy)) {
688
+ var _d = n.getBoundingClientRect(), width = _d.width, height = _d.height;
689
+ attributes = {
690
+ "class": attributes["class"],
691
+ rr_width: width + "px",
692
+ rr_height: height + "px"
693
+ };
694
+ needBlock = true;
695
+ }
696
+ if (tagName === 'iframe' && !keepIframeSrcFn(attributes.src)) {
697
+ if (!n.contentDocument) {
698
+ attributes.rr_src = attributes.src;
699
+ }
700
+ delete attributes.src;
701
+ }
702
+ return {
703
+ type: NodeType.Element,
704
+ tagName: tagName,
705
+ attributes: attributes,
706
+ childNodes: [],
707
+ isSVG: isSVGElement(n) || undefined,
708
+ needBlock: needBlock,
709
+ rootId: rootId
710
+ };
711
+ }
672
712
  function lowerIfExists(maybeAttr) {
673
713
  if (maybeAttr === undefined) {
674
714
  return '';
@@ -749,8 +789,8 @@ function slimDOMExcluded(sn, slimDOMOptions) {
749
789
  return false;
750
790
  }
751
791
  function serializeNodeWithId(n, options) {
752
- var doc = options.doc, mirror = options.mirror, blockClass = options.blockClass, blockSelector = options.blockSelector, maskTextClass = options.maskTextClass, maskTextSelector = options.maskTextSelector, _a = options.skipChild, skipChild = _a === void 0 ? false : _a, _b = options.inlineStylesheet, inlineStylesheet = _b === void 0 ? true : _b, _c = options.maskInputOptions, maskInputOptions = _c === void 0 ? {} : _c, maskTextFn = options.maskTextFn, maskInputFn = options.maskInputFn, slimDOMOptions = options.slimDOMOptions, _d = options.dataURLOptions, dataURLOptions = _d === void 0 ? {} : _d, _e = options.inlineImages, inlineImages = _e === void 0 ? false : _e, _f = options.recordCanvas, recordCanvas = _f === void 0 ? false : _f, onSerialize = options.onSerialize, onIframeLoad = options.onIframeLoad, _g = options.iframeLoadTimeout, iframeLoadTimeout = _g === void 0 ? 5000 : _g, onStylesheetLoad = options.onStylesheetLoad, _h = options.stylesheetLoadTimeout, stylesheetLoadTimeout = _h === void 0 ? 5000 : _h, _j = options.keepIframeSrcFn, keepIframeSrcFn = _j === void 0 ? function () { return false; } : _j, enableStrictPrivacy = options.enableStrictPrivacy;
753
- var _k = options.preserveWhiteSpace, preserveWhiteSpace = _k === void 0 ? true : _k;
792
+ var doc = options.doc, mirror = options.mirror, blockClass = options.blockClass, blockSelector = options.blockSelector, maskTextClass = options.maskTextClass, maskTextSelector = options.maskTextSelector, _a = options.skipChild, skipChild = _a === void 0 ? false : _a, _b = options.inlineStylesheet, inlineStylesheet = _b === void 0 ? true : _b, _c = options.maskInputOptions, maskInputOptions = _c === void 0 ? {} : _c, maskTextFn = options.maskTextFn, maskInputFn = options.maskInputFn, slimDOMOptions = options.slimDOMOptions, _d = options.dataURLOptions, dataURLOptions = _d === void 0 ? {} : _d, _e = options.inlineImages, inlineImages = _e === void 0 ? false : _e, _f = options.recordCanvas, recordCanvas = _f === void 0 ? false : _f, onSerialize = options.onSerialize, onIframeLoad = options.onIframeLoad, _g = options.iframeLoadTimeout, iframeLoadTimeout = _g === void 0 ? 5000 : _g, onStylesheetLoad = options.onStylesheetLoad, _h = options.stylesheetLoadTimeout, stylesheetLoadTimeout = _h === void 0 ? 5000 : _h, _j = options.keepIframeSrcFn, keepIframeSrcFn = _j === void 0 ? function () { return false; } : _j, _k = options.newlyAddedElement, newlyAddedElement = _k === void 0 ? false : _k, enableStrictPrivacy = options.enableStrictPrivacy;
793
+ var _l = options.preserveWhiteSpace, preserveWhiteSpace = _l === void 0 ? true : _l;
754
794
  var _serializedNode = serializeNode(n, {
755
795
  doc: doc,
756
796
  mirror: mirror,
@@ -766,6 +806,7 @@ function serializeNodeWithId(n, options) {
766
806
  inlineImages: inlineImages,
767
807
  recordCanvas: recordCanvas,
768
808
  keepIframeSrcFn: keepIframeSrcFn,
809
+ newlyAddedElement: newlyAddedElement,
769
810
  enableStrictPrivacy: enableStrictPrivacy
770
811
  });
771
812
  if (!_serializedNode) {
@@ -802,12 +843,6 @@ function serializeNodeWithId(n, options) {
802
843
  clone.src = '';
803
844
  mirror.add(clone, serializedNode);
804
845
  }
805
- if (serializedNode.tagName === 'link') {
806
- var clone = n.cloneNode();
807
- clone.href = '';
808
- clone.innerText = serializedNode.attributes._cssText;
809
- mirror.add(clone, serializedNode);
810
- }
811
846
  delete serializedNode.needBlock;
812
847
  if (n.shadowRoot)
813
848
  serializedNode.isShadowHost = true;
@@ -845,16 +880,16 @@ function serializeNodeWithId(n, options) {
845
880
  keepIframeSrcFn: keepIframeSrcFn,
846
881
  enableStrictPrivacy: enableStrictPrivacy
847
882
  };
848
- for (var _i = 0, _l = Array.from(n.childNodes); _i < _l.length; _i++) {
849
- var childN = _l[_i];
883
+ for (var _i = 0, _m = Array.from(n.childNodes); _i < _m.length; _i++) {
884
+ var childN = _m[_i];
850
885
  var serializedChildNode = serializeNodeWithId(childN, bypassOptions);
851
886
  if (serializedChildNode) {
852
887
  serializedNode.childNodes.push(serializedChildNode);
853
888
  }
854
889
  }
855
890
  if (isElement(n) && n.shadowRoot) {
856
- for (var _m = 0, _o = Array.from(n.shadowRoot.childNodes); _m < _o.length; _m++) {
857
- var childN = _o[_m];
891
+ for (var _o = 0, _p = Array.from(n.shadowRoot.childNodes); _o < _p.length; _o++) {
892
+ var childN = _p[_o];
858
893
  var serializedChildNode = serializeNodeWithId(childN, bypassOptions);
859
894
  if (serializedChildNode) {
860
895
  serializedChildNode.isShadow = true;
@@ -891,6 +926,8 @@ function serializeNodeWithId(n, options) {
891
926
  onSerialize: onSerialize,
892
927
  onIframeLoad: onIframeLoad,
893
928
  iframeLoadTimeout: iframeLoadTimeout,
929
+ onStylesheetLoad: onStylesheetLoad,
930
+ stylesheetLoadTimeout: stylesheetLoadTimeout,
894
931
  keepIframeSrcFn: keepIframeSrcFn,
895
932
  enableStrictPrivacy: enableStrictPrivacy
896
933
  });
@@ -924,8 +961,9 @@ function serializeNodeWithId(n, options) {
924
961
  preserveWhiteSpace: preserveWhiteSpace,
925
962
  onSerialize: onSerialize,
926
963
  onIframeLoad: onIframeLoad,
927
- onStylesheetLoad: onStylesheetLoad,
928
964
  iframeLoadTimeout: iframeLoadTimeout,
965
+ onStylesheetLoad: onStylesheetLoad,
966
+ stylesheetLoadTimeout: stylesheetLoadTimeout,
929
967
  keepIframeSrcFn: keepIframeSrcFn,
930
968
  enableStrictPrivacy: enableStrictPrivacy
931
969
  });
@@ -1003,7 +1041,9 @@ function snapshot(n, options) {
1003
1041
  onIframeLoad: onIframeLoad,
1004
1042
  iframeLoadTimeout: iframeLoadTimeout,
1005
1043
  onStylesheetLoad: onStylesheetLoad,
1006
- stylesheetLoadTimeout: stylesheetLoadTimeout, keepIframeSrcFn: keepIframeSrcFn,
1044
+ stylesheetLoadTimeout: stylesheetLoadTimeout,
1045
+ keepIframeSrcFn: keepIframeSrcFn,
1046
+ newlyAddedElement: false,
1007
1047
  enableStrictPrivacy: enableStrictPrivacy
1008
1048
  });
1009
1049
  }
@@ -1139,33 +1179,26 @@ const isCanvasNode = (node) => {
1139
1179
  }
1140
1180
  return false;
1141
1181
  };
1142
- function isBlocked(node, blockClass) {
1182
+ function isBlocked(node, blockClass, checkAncestors) {
1143
1183
  if (!node) {
1144
1184
  return false;
1145
1185
  }
1146
- if (node.nodeType === node.ELEMENT_NODE) {
1147
- let needBlock = false;
1148
- if (typeof blockClass === 'string') {
1149
- if (node.closest !== undefined) {
1150
- return node.closest('.' + blockClass) !== null;
1151
- }
1152
- else {
1153
- needBlock = node.classList.contains(blockClass);
1154
- }
1155
- }
1156
- else {
1157
- node.classList.forEach((className) => {
1158
- if (blockClass.test(className)) {
1159
- needBlock = true;
1160
- }
1161
- });
1162
- }
1163
- return needBlock || isBlocked(node.parentNode, blockClass);
1186
+ const el = node.nodeType === node.ELEMENT_NODE
1187
+ ? node
1188
+ : node.parentElement;
1189
+ if (!el)
1190
+ return false;
1191
+ if (typeof blockClass === 'string') {
1192
+ if (el.classList.contains(blockClass))
1193
+ return true;
1194
+ if (checkAncestors && el.closest('.' + blockClass) !== null)
1195
+ return true;
1164
1196
  }
1165
- if (node.nodeType === node.TEXT_NODE) {
1166
- return isBlocked(node.parentNode, blockClass);
1197
+ else {
1198
+ if (classMatchesRegex(el, blockClass, checkAncestors))
1199
+ return true;
1167
1200
  }
1168
- return isBlocked(node.parentNode, blockClass);
1201
+ return false;
1169
1202
  }
1170
1203
  function isSerialized(n, mirror) {
1171
1204
  return mirror.getId(n) !== -1;
@@ -1469,6 +1502,7 @@ class MutationBuffer {
1469
1502
  onStylesheetLoad: (link, childSn) => {
1470
1503
  this.stylesheetManager.attachStylesheet(link, childSn, this.mirror);
1471
1504
  },
1505
+ newlyAddedElement: true,
1472
1506
  });
1473
1507
  if (sn) {
1474
1508
  adds.push({
@@ -1577,7 +1611,8 @@ class MutationBuffer {
1577
1611
  switch (m.type) {
1578
1612
  case 'characterData': {
1579
1613
  const value = m.target.textContent;
1580
- if (!isBlocked(m.target, this.blockClass) && value !== m.oldValue) {
1614
+ if (!isBlocked(m.target, this.blockClass, false) &&
1615
+ value !== m.oldValue) {
1581
1616
  this.texts.push({
1582
1617
  value: needMaskingText(m.target, this.maskTextClass, this.maskTextSelector) && value
1583
1618
  ? this.maskTextFn
@@ -1601,7 +1636,8 @@ class MutationBuffer {
1601
1636
  maskInputFn: this.maskInputFn,
1602
1637
  });
1603
1638
  }
1604
- if (isBlocked(m.target, this.blockClass) || value === m.oldValue) {
1639
+ if (isBlocked(m.target, this.blockClass, false) ||
1640
+ value === m.oldValue) {
1605
1641
  return;
1606
1642
  }
1607
1643
  let item = this.attributes.find((a) => a.node === m.target);
@@ -1655,13 +1691,15 @@ class MutationBuffer {
1655
1691
  break;
1656
1692
  }
1657
1693
  case 'childList': {
1694
+ if (isBlocked(m.target, this.blockClass, true))
1695
+ return;
1658
1696
  m.addedNodes.forEach((n) => this.genAdds(n, m.target));
1659
1697
  m.removedNodes.forEach((n) => {
1660
1698
  const nodeId = this.mirror.getId(n);
1661
1699
  const parentId = isShadowRoot(m.target)
1662
1700
  ? this.mirror.getId(m.target.host)
1663
1701
  : this.mirror.getId(m.target);
1664
- if (isBlocked(m.target, this.blockClass) ||
1702
+ if (isBlocked(m.target, this.blockClass, false) ||
1665
1703
  isIgnored(n, this.mirror) ||
1666
1704
  !isSerialized(n, this.mirror)) {
1667
1705
  return;
@@ -1690,16 +1728,13 @@ class MutationBuffer {
1690
1728
  }
1691
1729
  };
1692
1730
  this.genAdds = (n, target) => {
1693
- if (target && isBlocked(target, this.blockClass)) {
1694
- return;
1695
- }
1696
- if (this.mirror.getMeta(n)) {
1731
+ if (this.mirror.hasNode(n)) {
1697
1732
  if (isIgnored(n, this.mirror)) {
1698
1733
  return;
1699
1734
  }
1700
1735
  this.movedSet.add(n);
1701
1736
  let targetId = null;
1702
- if (target && this.mirror.getMeta(target)) {
1737
+ if (target && this.mirror.hasNode(target)) {
1703
1738
  targetId = this.mirror.getId(target);
1704
1739
  }
1705
1740
  if (targetId && targetId !== -1) {
@@ -1710,7 +1745,7 @@ class MutationBuffer {
1710
1745
  this.addedSet.add(n);
1711
1746
  this.droppedSet.delete(n);
1712
1747
  }
1713
- if (!isBlocked(n, this.blockClass))
1748
+ if (!isBlocked(n, this.blockClass, false))
1714
1749
  n.childNodes.forEach((childN) => this.genAdds(childN));
1715
1750
  };
1716
1751
  }
@@ -1770,6 +1805,11 @@ function deepDelete(addsSet, n) {
1770
1805
  n.childNodes.forEach((childN) => deepDelete(addsSet, childN));
1771
1806
  }
1772
1807
  function isParentRemoved(removes, n, mirror) {
1808
+ if (removes.length === 0)
1809
+ return false;
1810
+ return _isParentRemoved(removes, n, mirror);
1811
+ }
1812
+ function _isParentRemoved(removes, n, mirror) {
1773
1813
  const { parentNode } = n;
1774
1814
  if (!parentNode) {
1775
1815
  return false;
@@ -1778,9 +1818,14 @@ function isParentRemoved(removes, n, mirror) {
1778
1818
  if (removes.some((r) => r.id === parentId)) {
1779
1819
  return true;
1780
1820
  }
1781
- return isParentRemoved(removes, parentNode, mirror);
1821
+ return _isParentRemoved(removes, parentNode, mirror);
1782
1822
  }
1783
1823
  function isAncestorInSet(set, n) {
1824
+ if (set.size === 0)
1825
+ return false;
1826
+ return _isAncestorInSet(set, n);
1827
+ }
1828
+ function _isAncestorInSet(set, n) {
1784
1829
  const { parentNode } = n;
1785
1830
  if (!parentNode) {
1786
1831
  return false;
@@ -1788,7 +1833,7 @@ function isAncestorInSet(set, n) {
1788
1833
  if (set.has(parentNode)) {
1789
1834
  return true;
1790
1835
  }
1791
- return isAncestorInSet(set, parentNode);
1836
+ return _isAncestorInSet(set, parentNode);
1792
1837
  }
1793
1838
 
1794
1839
  const mutationBuffers = [];
@@ -1898,7 +1943,7 @@ function initMouseInteractionObserver({ mouseInteractionCb, doc, mirror, blockCl
1898
1943
  const getHandler = (eventKey) => {
1899
1944
  return (event) => {
1900
1945
  const target = getEventTarget(event);
1901
- if (isBlocked(target, blockClass) ||
1946
+ if (isBlocked(target, blockClass, true) ||
1902
1947
  isCanvasNode(target)) {
1903
1948
  return;
1904
1949
  }
@@ -1932,7 +1977,7 @@ function initMouseInteractionObserver({ mouseInteractionCb, doc, mirror, blockCl
1932
1977
  function initScrollObserver({ scrollCb, doc, mirror, blockClass, sampling, }) {
1933
1978
  const updatePosition = throttle((evt) => {
1934
1979
  const target = getEventTarget(evt);
1935
- if (!target || isBlocked(target, blockClass)) {
1980
+ if (!target || isBlocked(target, blockClass, true)) {
1936
1981
  return;
1937
1982
  }
1938
1983
  const id = mirror.getId(target);
@@ -1988,7 +2033,7 @@ function initInputObserver({ inputCb, doc, mirror, blockClass, ignoreClass, mask
1988
2033
  if (!target ||
1989
2034
  !target.tagName ||
1990
2035
  INPUT_TAGS.indexOf(target.tagName) < 0 ||
1991
- isBlocked(target, blockClass)) {
2036
+ isBlocked(target, blockClass, true)) {
1992
2037
  return;
1993
2038
  }
1994
2039
  const type = target.type;
@@ -2123,8 +2168,8 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror }, { win }) {
2123
2168
  const unmodifiedFunctions = {};
2124
2169
  Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
2125
2170
  unmodifiedFunctions[typeKey] = {
2126
- insertRule: (type).prototype.insertRule,
2127
- deleteRule: (type).prototype.deleteRule,
2171
+ insertRule: type.prototype.insertRule,
2172
+ deleteRule: type.prototype.deleteRule,
2128
2173
  };
2129
2174
  type.prototype.insertRule = function (rule, index) {
2130
2175
  const id = mirror.getId(this.parentStyleSheet.ownerNode);
@@ -2205,7 +2250,7 @@ function initStyleDeclarationObserver({ styleDeclarationCb, mirror }, { win }) {
2205
2250
  function initMediaInteractionObserver({ mediaInteractionCb, blockClass, mirror, sampling, }) {
2206
2251
  const handler = (type) => throttle((event) => {
2207
2252
  const target = getEventTarget(event);
2208
- if (!target || isBlocked(target, blockClass)) {
2253
+ if (!target || isBlocked(target, blockClass, true)) {
2209
2254
  return;
2210
2255
  }
2211
2256
  const { currentTime, volume, muted } = target;
@@ -2639,7 +2684,7 @@ function initCanvas2DMutationObserver(cb, win, blockClass, mirror) {
2639
2684
  }
2640
2685
  const restoreHandler = patch(win.CanvasRenderingContext2D.prototype, prop, function (original) {
2641
2686
  return function (...args) {
2642
- if (!isBlocked(this.canvas, blockClass)) {
2687
+ if (!isBlocked(this.canvas, blockClass, true)) {
2643
2688
  setTimeout(() => {
2644
2689
  const recordArgs = serializeArgs([...args], win, this);
2645
2690
  cb(this.canvas, {
@@ -2678,9 +2723,9 @@ function initCanvasContextObserver(win, blockClass) {
2678
2723
  try {
2679
2724
  const restoreHandler = patch(win.HTMLCanvasElement.prototype, 'getContext', function (original) {
2680
2725
  return function (contextType, ...args) {
2681
- if (!isBlocked(this, blockClass)) {
2726
+ if (!isBlocked(this, blockClass, true)) {
2682
2727
  if (!('__context' in this))
2683
- (this).__context = contextType;
2728
+ this.__context = contextType;
2684
2729
  }
2685
2730
  return original.apply(this, [contextType, ...args]);
2686
2731
  };
@@ -2707,8 +2752,7 @@ function patchGLPrototype(prototype, type, cb, blockClass, mirror, win) {
2707
2752
  return function (...args) {
2708
2753
  const result = original.apply(this, args);
2709
2754
  saveWebGLVar(result, win, prototype);
2710
- if (!isBlocked(this.canvas, blockClass)) {
2711
- const id = mirror.getId(this.canvas);
2755
+ if (!isBlocked(this.canvas, blockClass, true)) {
2712
2756
  const recordArgs = serializeArgs([...args], win, prototype);
2713
2757
  const mutation = {
2714
2758
  type,
@@ -3187,6 +3231,9 @@ function record(options = {}) {
3187
3231
  if (isSerializedIframe(n, mirror)) {
3188
3232
  iframeManager.addIframe(n);
3189
3233
  }
3234
+ if (isSerializedStylesheet(n, mirror)) {
3235
+ stylesheetManager.addStylesheet(n);
3236
+ }
3190
3237
  if (hasShadowRoot(n)) {
3191
3238
  shadowDomManager.addShadowRoot(n.shadowRoot, document);
3192
3239
  }
@@ -3196,7 +3243,7 @@ function record(options = {}) {
3196
3243
  shadowDomManager.observeAttachShadow(iframe);
3197
3244
  },
3198
3245
  onStylesheetLoad: (linkEl, childSn) => {
3199
- this.stylesheetManager.attachStylesheet(linkEl, childSn, this.mirror);
3246
+ stylesheetManager.attachStylesheet(linkEl, childSn, mirror);
3200
3247
  },
3201
3248
  keepIframeSrcFn,
3202
3249
  });