@appsurify-testmap/rrweb-record 2.1.0-alpha.7 → 2.1.1-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/rrweb-record.cjs +574 -149
- package/dist/rrweb-record.cjs.map +1 -1
- package/dist/rrweb-record.js +574 -149
- package/dist/rrweb-record.js.map +1 -1
- package/dist/rrweb-record.umd.cjs +577 -151
- package/dist/rrweb-record.umd.cjs.map +3 -3
- package/dist/rrweb-record.umd.min.cjs +26 -26
- package/dist/rrweb-record.umd.min.cjs.map +3 -3
- package/package.json +4 -4
package/dist/rrweb-record.cjs
CHANGED
|
@@ -170,6 +170,41 @@ function patch$1(source, name, replacement) {
|
|
|
170
170
|
};
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
|
+
function describeNode$1(el) {
|
|
174
|
+
const tag = el.tagName.toLowerCase();
|
|
175
|
+
const id = el.id ? `#${el.id}` : "";
|
|
176
|
+
const classes = el.classList.length ? "." + Array.from(el.classList).join(".") : "";
|
|
177
|
+
return `${tag}${id}${classes}`;
|
|
178
|
+
}
|
|
179
|
+
function getElementVisibility$1(el) {
|
|
180
|
+
var _a2, _b;
|
|
181
|
+
const win = ((_a2 = el.ownerDocument) == null ? void 0 : _a2.defaultView) ?? window;
|
|
182
|
+
const rect = el.getBoundingClientRect();
|
|
183
|
+
const viewportWidth = win.innerWidth || win.document.documentElement.clientWidth || 0;
|
|
184
|
+
const viewportHeight = win.innerHeight || win.document.documentElement.clientHeight || 0;
|
|
185
|
+
const isRectVisible = rect.width > 0 && rect.height > 0 && rect.bottom > 0 && rect.right > 0 && rect.top < viewportHeight && rect.left < viewportWidth;
|
|
186
|
+
const style = (_b = win.getComputedStyle) == null ? void 0 : _b.call(win, el);
|
|
187
|
+
const isStyleVisible2 = !!style && style.display !== "none" && style.visibility !== "hidden" && (parseFloat(style.opacity) || 0) > 0;
|
|
188
|
+
const isVisible = isStyleVisible2 && isRectVisible;
|
|
189
|
+
let ratio = 0;
|
|
190
|
+
if (isVisible) {
|
|
191
|
+
const xOverlap = Math.max(
|
|
192
|
+
0,
|
|
193
|
+
Math.min(rect.right, viewportWidth) - Math.max(rect.left, 0)
|
|
194
|
+
);
|
|
195
|
+
const yOverlap = Math.max(
|
|
196
|
+
0,
|
|
197
|
+
Math.min(rect.bottom, viewportHeight) - Math.max(rect.top, 0)
|
|
198
|
+
);
|
|
199
|
+
const intersectionArea = xOverlap * yOverlap;
|
|
200
|
+
const elementArea = rect.width * rect.height;
|
|
201
|
+
ratio = elementArea > 0 ? intersectionArea / elementArea : 0;
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
isVisible,
|
|
205
|
+
ratio
|
|
206
|
+
};
|
|
207
|
+
}
|
|
173
208
|
const index$1 = {
|
|
174
209
|
childNodes: childNodes$1,
|
|
175
210
|
parentNode: parentNode$1,
|
|
@@ -183,7 +218,9 @@ const index$1 = {
|
|
|
183
218
|
querySelector: querySelector$1,
|
|
184
219
|
querySelectorAll: querySelectorAll$1,
|
|
185
220
|
mutationObserver: mutationObserverCtor$1,
|
|
186
|
-
patch: patch$1
|
|
221
|
+
patch: patch$1,
|
|
222
|
+
describeNode: describeNode$1,
|
|
223
|
+
getElementVisibility: getElementVisibility$1
|
|
187
224
|
};
|
|
188
225
|
function isElement(n2) {
|
|
189
226
|
return n2.nodeType === n2.ELEMENT_NODE;
|
|
@@ -557,71 +594,95 @@ function splitCssText(cssText, style, _testNoPxNorm = false) {
|
|
|
557
594
|
function markCssSplits(cssText, style) {
|
|
558
595
|
return splitCssText(cssText, style).join("/* rr_split */");
|
|
559
596
|
}
|
|
560
|
-
function
|
|
561
|
-
|
|
562
|
-
|
|
597
|
+
function isSelectorUnique(selector, target) {
|
|
598
|
+
try {
|
|
599
|
+
const matches = document.querySelectorAll(selector);
|
|
600
|
+
return matches.length === 1 && matches[0] === target;
|
|
601
|
+
} catch {
|
|
602
|
+
return false;
|
|
563
603
|
}
|
|
564
|
-
|
|
565
|
-
|
|
604
|
+
}
|
|
605
|
+
function buildSelector(node2) {
|
|
606
|
+
if (!(node2 instanceof Element)) return null;
|
|
607
|
+
if (node2.id) {
|
|
608
|
+
return `#${CSS.escape(node2.id)}`;
|
|
566
609
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
}
|
|
572
|
-
if (element.tagName && element.tagName.toLowerCase() === "html") {
|
|
573
|
-
return "/html";
|
|
574
|
-
}
|
|
575
|
-
if (element === document.head) {
|
|
576
|
-
return "/html/head";
|
|
577
|
-
}
|
|
578
|
-
if (element === document.body) {
|
|
579
|
-
return "/html/body";
|
|
580
|
-
}
|
|
581
|
-
const parentNode2 = element.parentNode;
|
|
582
|
-
if (!parentNode2) {
|
|
583
|
-
return "";
|
|
584
|
-
}
|
|
585
|
-
const siblings = Array.from(parentNode2.children).filter(
|
|
586
|
-
(sibling) => sibling.tagName === element.tagName
|
|
587
|
-
);
|
|
588
|
-
const index2 = siblings.length > 1 ? `[${siblings.indexOf(element) + 1}]` : "";
|
|
589
|
-
return `${getXPath(parentNode2)}/${element.tagName.toLowerCase()}${index2}`;
|
|
610
|
+
const parts = [];
|
|
611
|
+
const tag = node2.tagName.toLowerCase();
|
|
612
|
+
if (node2.classList.length) {
|
|
613
|
+
parts.push(...Array.from(node2.classList).map((cls) => `.${CSS.escape(cls)}`));
|
|
590
614
|
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
return "";
|
|
615
|
+
Array.from(node2.attributes).forEach((attr) => {
|
|
616
|
+
if (attr.name.startsWith("data-")) {
|
|
617
|
+
parts.push(`[${attr.name}="${CSS.escape(attr.value)}"]`);
|
|
595
618
|
}
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
619
|
+
});
|
|
620
|
+
const shortSelector = `${tag}${parts.join("")}`;
|
|
621
|
+
if (isSelectorUnique(shortSelector, node2)) {
|
|
622
|
+
return shortSelector;
|
|
623
|
+
}
|
|
624
|
+
const pathParts = [];
|
|
625
|
+
let current = node2;
|
|
626
|
+
while (current && current.nodeType === Node.ELEMENT_NODE) {
|
|
627
|
+
const parent = current.parentElement;
|
|
628
|
+
const tagName = current.tagName.toLowerCase();
|
|
629
|
+
let nth = "";
|
|
630
|
+
if (parent) {
|
|
631
|
+
const siblings = Array.from(parent.children).filter(
|
|
632
|
+
(el) => el.tagName.toLowerCase() === tagName
|
|
633
|
+
);
|
|
634
|
+
if (siblings.length > 1) {
|
|
635
|
+
nth = `:nth-of-type(${siblings.indexOf(current) + 1})`;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
pathParts.unshift(`${tagName}${nth}`);
|
|
639
|
+
current = parent;
|
|
640
|
+
}
|
|
641
|
+
return pathParts.join(" > ") || null;
|
|
642
|
+
}
|
|
643
|
+
function buildXPath(node2) {
|
|
644
|
+
switch (node2.nodeType) {
|
|
645
|
+
case Node.DOCUMENT_NODE:
|
|
646
|
+
return "/";
|
|
647
|
+
case Node.DOCUMENT_TYPE_NODE:
|
|
648
|
+
return "/html/doctype";
|
|
649
|
+
case Node.ELEMENT_NODE: {
|
|
650
|
+
const element = node2;
|
|
651
|
+
if (element.id) {
|
|
652
|
+
return `//*[@id="${CSS.escape(element.id)}"]`;
|
|
653
|
+
}
|
|
654
|
+
if (element.tagName.toLowerCase() === "html") return "/html";
|
|
655
|
+
if (element === document.head) return "/html/head";
|
|
656
|
+
if (element === document.body) return "/html/body";
|
|
657
|
+
const parent = element.parentNode;
|
|
658
|
+
if (!parent) return "";
|
|
659
|
+
const tag = element.tagName.toLowerCase();
|
|
660
|
+
const siblings = Array.from(parent.children).filter(
|
|
661
|
+
(el) => el.tagName.toLowerCase() === tag
|
|
662
|
+
);
|
|
663
|
+
const index2 = siblings.length > 1 ? `[${siblings.indexOf(element) + 1}]` : "";
|
|
664
|
+
return `${buildXPath(parent)}/${tag}${index2}`;
|
|
665
|
+
}
|
|
666
|
+
case Node.TEXT_NODE:
|
|
667
|
+
case Node.CDATA_SECTION_NODE:
|
|
668
|
+
case Node.COMMENT_NODE: {
|
|
669
|
+
const parent = node2.parentNode;
|
|
670
|
+
if (!parent) return "";
|
|
671
|
+
const typeMap = {
|
|
672
|
+
[Node.TEXT_NODE]: "text()",
|
|
673
|
+
[Node.CDATA_SECTION_NODE]: "text()",
|
|
674
|
+
// CDATA ≡ text() в XPath
|
|
675
|
+
[Node.COMMENT_NODE]: "comment()"
|
|
676
|
+
};
|
|
677
|
+
const sameTypeSiblings = Array.from(parent.childNodes).filter(
|
|
678
|
+
(sibling) => sibling.nodeType === node2.nodeType
|
|
679
|
+
);
|
|
680
|
+
const index2 = sameTypeSiblings.length > 1 ? `[${sameTypeSiblings.indexOf(node2)}]` : "";
|
|
681
|
+
return `${buildXPath(parent)}/${typeMap[node2.nodeType]}${index2}`;
|
|
606
682
|
}
|
|
607
|
-
|
|
608
|
-
(sibling) => sibling.nodeType === Node.CDATA_SECTION_NODE
|
|
609
|
-
);
|
|
610
|
-
const index2 = cdataSiblings.length > 1 ? `[${cdataSiblings.indexOf(node2) + 1}]` : "";
|
|
611
|
-
return `${getXPath(parent)}/text()${index2}`;
|
|
612
|
-
}
|
|
613
|
-
if (node2.nodeType === Node.COMMENT_NODE) {
|
|
614
|
-
const parent = node2.parentNode;
|
|
615
|
-
if (!parent) {
|
|
683
|
+
default:
|
|
616
684
|
return "";
|
|
617
|
-
}
|
|
618
|
-
const commentSiblings = Array.from(parent.childNodes).filter(
|
|
619
|
-
(sibling) => sibling.nodeType === Node.COMMENT_NODE
|
|
620
|
-
);
|
|
621
|
-
const index2 = commentSiblings.length > 1 ? `[${commentSiblings.indexOf(node2) + 1}]` : "";
|
|
622
|
-
return `${getXPath(parent)}/comment()${index2}`;
|
|
623
685
|
}
|
|
624
|
-
return "";
|
|
625
686
|
}
|
|
626
687
|
function isTextVisible(n2) {
|
|
627
688
|
var _a2;
|
|
@@ -637,20 +698,9 @@ function isTextVisible(n2) {
|
|
|
637
698
|
const textContent2 = (_a2 = n2.textContent) == null ? void 0 : _a2.trim();
|
|
638
699
|
return textContent2 !== "";
|
|
639
700
|
}
|
|
640
|
-
function isElementVisible(
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
const style = win ? win.getComputedStyle(n2) : null;
|
|
644
|
-
const isStyleVisible = style != null && style.display !== "none" && style.visibility !== "hidden" && parseFloat(style.opacity) !== 0;
|
|
645
|
-
const rect = n2.getBoundingClientRect();
|
|
646
|
-
const result2 = isStyleVisible && isRectVisible(rect);
|
|
647
|
-
return result2;
|
|
648
|
-
}
|
|
649
|
-
function isRectVisible(rect, win = window) {
|
|
650
|
-
var _a2, _b, _c, _d;
|
|
651
|
-
const height = (win == null ? void 0 : win.innerHeight) ?? ((_b = (_a2 = win == null ? void 0 : win.document) == null ? void 0 : _a2.documentElement) == null ? void 0 : _b.clientHeight) ?? 0;
|
|
652
|
-
const width = (win == null ? void 0 : win.innerWidth) ?? ((_d = (_c = win == null ? void 0 : win.document) == null ? void 0 : _c.documentElement) == null ? void 0 : _d.clientWidth) ?? 0;
|
|
653
|
-
return rect.width > 0 && rect.height > 0 && rect.top >= 0 && rect.left >= 0 && rect.bottom <= height && rect.right <= width;
|
|
701
|
+
function isElementVisible(el) {
|
|
702
|
+
const visibility = index$1.getElementVisibility(el);
|
|
703
|
+
return visibility.isVisible;
|
|
654
704
|
}
|
|
655
705
|
const interactiveEvents$1 = [
|
|
656
706
|
"change",
|
|
@@ -883,9 +933,6 @@ function transformAttribute(doc, tagName, name, value) {
|
|
|
883
933
|
function ignoreAttribute(tagName, name, _value) {
|
|
884
934
|
return (tagName === "video" || tagName === "audio") && name === "autoplay";
|
|
885
935
|
}
|
|
886
|
-
function isIncludeAttribute(name, include) {
|
|
887
|
-
return typeof include === "string" ? name.includes(include) : include.test(name);
|
|
888
|
-
}
|
|
889
936
|
function isExcludeAttribute(name, exclude) {
|
|
890
937
|
return typeof exclude === "string" ? name.includes(exclude) : exclude.test(name);
|
|
891
938
|
}
|
|
@@ -1019,7 +1066,6 @@ function serializeNode(n2, options) {
|
|
|
1019
1066
|
blockClass,
|
|
1020
1067
|
blockSelector,
|
|
1021
1068
|
excludeAttribute,
|
|
1022
|
-
includeAttribute,
|
|
1023
1069
|
needsMask,
|
|
1024
1070
|
inlineStylesheet,
|
|
1025
1071
|
maskInputOptions = {},
|
|
@@ -1033,22 +1079,19 @@ function serializeNode(n2, options) {
|
|
|
1033
1079
|
cssCaptured = false
|
|
1034
1080
|
} = options;
|
|
1035
1081
|
const rootId = getRootId(doc, mirror2);
|
|
1036
|
-
const xPath = getXPath(n2);
|
|
1037
1082
|
switch (n2.nodeType) {
|
|
1038
1083
|
case n2.DOCUMENT_NODE:
|
|
1039
1084
|
if (n2.compatMode !== "CSS1Compat") {
|
|
1040
1085
|
return {
|
|
1041
1086
|
type: NodeType$3.Document,
|
|
1042
1087
|
childNodes: [],
|
|
1043
|
-
xPath,
|
|
1044
1088
|
compatMode: n2.compatMode
|
|
1045
1089
|
// probably "BackCompat"
|
|
1046
1090
|
};
|
|
1047
1091
|
} else {
|
|
1048
1092
|
return {
|
|
1049
1093
|
type: NodeType$3.Document,
|
|
1050
|
-
childNodes: []
|
|
1051
|
-
xPath
|
|
1094
|
+
childNodes: []
|
|
1052
1095
|
};
|
|
1053
1096
|
}
|
|
1054
1097
|
case n2.DOCUMENT_TYPE_NODE:
|
|
@@ -1057,8 +1100,7 @@ function serializeNode(n2, options) {
|
|
|
1057
1100
|
name: n2.name,
|
|
1058
1101
|
publicId: n2.publicId,
|
|
1059
1102
|
systemId: n2.systemId,
|
|
1060
|
-
rootId
|
|
1061
|
-
xPath
|
|
1103
|
+
rootId
|
|
1062
1104
|
};
|
|
1063
1105
|
case n2.ELEMENT_NODE:
|
|
1064
1106
|
return serializeElementNode(n2, {
|
|
@@ -1066,7 +1108,6 @@ function serializeNode(n2, options) {
|
|
|
1066
1108
|
blockClass,
|
|
1067
1109
|
blockSelector,
|
|
1068
1110
|
excludeAttribute,
|
|
1069
|
-
includeAttribute,
|
|
1070
1111
|
inlineStylesheet,
|
|
1071
1112
|
maskInputOptions,
|
|
1072
1113
|
maskInputFn,
|
|
@@ -1075,8 +1116,7 @@ function serializeNode(n2, options) {
|
|
|
1075
1116
|
recordCanvas,
|
|
1076
1117
|
keepIframeSrcFn,
|
|
1077
1118
|
newlyAddedElement,
|
|
1078
|
-
rootId
|
|
1079
|
-
xPath
|
|
1119
|
+
rootId
|
|
1080
1120
|
});
|
|
1081
1121
|
case n2.TEXT_NODE:
|
|
1082
1122
|
return serializeTextNode(n2, {
|
|
@@ -1084,22 +1124,19 @@ function serializeNode(n2, options) {
|
|
|
1084
1124
|
needsMask,
|
|
1085
1125
|
maskTextFn,
|
|
1086
1126
|
rootId,
|
|
1087
|
-
cssCaptured
|
|
1088
|
-
xPath
|
|
1127
|
+
cssCaptured
|
|
1089
1128
|
});
|
|
1090
1129
|
case n2.CDATA_SECTION_NODE:
|
|
1091
1130
|
return {
|
|
1092
1131
|
type: NodeType$3.CDATA,
|
|
1093
1132
|
textContent: "",
|
|
1094
|
-
rootId
|
|
1095
|
-
xPath
|
|
1133
|
+
rootId
|
|
1096
1134
|
};
|
|
1097
1135
|
case n2.COMMENT_NODE:
|
|
1098
1136
|
return {
|
|
1099
1137
|
type: NodeType$3.Comment,
|
|
1100
1138
|
textContent: index$1.textContent(n2) || "",
|
|
1101
|
-
rootId
|
|
1102
|
-
xPath
|
|
1139
|
+
rootId
|
|
1103
1140
|
};
|
|
1104
1141
|
default:
|
|
1105
1142
|
return false;
|
|
@@ -1111,7 +1148,7 @@ function getRootId(doc, mirror2) {
|
|
|
1111
1148
|
return docId === 1 ? void 0 : docId;
|
|
1112
1149
|
}
|
|
1113
1150
|
function serializeTextNode(n2, options) {
|
|
1114
|
-
const { needsMask, maskTextFn, rootId, cssCaptured
|
|
1151
|
+
const { needsMask, maskTextFn, rootId, cssCaptured } = options;
|
|
1115
1152
|
const parent = index$1.parentNode(n2);
|
|
1116
1153
|
const parentTagName = parent && parent.tagName;
|
|
1117
1154
|
let textContent2 = "";
|
|
@@ -1128,15 +1165,10 @@ function serializeTextNode(n2, options) {
|
|
|
1128
1165
|
if (!isStyle && !isScript && textContent2 && needsMask) {
|
|
1129
1166
|
textContent2 = maskTextFn ? maskTextFn(textContent2, index$1.parentElement(n2)) : textContent2.replace(/[\S]/g, "*");
|
|
1130
1167
|
}
|
|
1131
|
-
const isVisible = isTextVisible(n2);
|
|
1132
|
-
const isInteractive = isElementInteractive(n2);
|
|
1133
1168
|
return {
|
|
1134
1169
|
type: NodeType$3.Text,
|
|
1135
1170
|
textContent: textContent2 || "",
|
|
1136
|
-
rootId
|
|
1137
|
-
isVisible,
|
|
1138
|
-
isInteractive,
|
|
1139
|
-
xPath
|
|
1171
|
+
rootId
|
|
1140
1172
|
};
|
|
1141
1173
|
}
|
|
1142
1174
|
function serializeElementNode(n2, options) {
|
|
@@ -1145,7 +1177,6 @@ function serializeElementNode(n2, options) {
|
|
|
1145
1177
|
blockClass,
|
|
1146
1178
|
blockSelector,
|
|
1147
1179
|
excludeAttribute,
|
|
1148
|
-
includeAttribute,
|
|
1149
1180
|
inlineStylesheet,
|
|
1150
1181
|
maskInputOptions = {},
|
|
1151
1182
|
maskInputFn,
|
|
@@ -1154,8 +1185,7 @@ function serializeElementNode(n2, options) {
|
|
|
1154
1185
|
recordCanvas,
|
|
1155
1186
|
keepIframeSrcFn,
|
|
1156
1187
|
newlyAddedElement = false,
|
|
1157
|
-
rootId
|
|
1158
|
-
xPath
|
|
1188
|
+
rootId
|
|
1159
1189
|
} = options;
|
|
1160
1190
|
const needBlock = _isBlockedElement(n2, blockClass, blockSelector);
|
|
1161
1191
|
const tagName = getValidTagName$1(n2);
|
|
@@ -1163,7 +1193,7 @@ function serializeElementNode(n2, options) {
|
|
|
1163
1193
|
const len = n2.attributes.length;
|
|
1164
1194
|
for (let i2 = 0; i2 < len; i2++) {
|
|
1165
1195
|
const attr = n2.attributes[i2];
|
|
1166
|
-
if (isExcludeAttribute(attr.name, excludeAttribute)
|
|
1196
|
+
if (isExcludeAttribute(attr.name, excludeAttribute)) {
|
|
1167
1197
|
continue;
|
|
1168
1198
|
}
|
|
1169
1199
|
if (!ignoreAttribute(tagName, attr.name, attr.value)) {
|
|
@@ -1325,8 +1355,6 @@ function serializeElementNode(n2, options) {
|
|
|
1325
1355
|
if (customElements.get(tagName)) isCustomElement = true;
|
|
1326
1356
|
} catch (e2) {
|
|
1327
1357
|
}
|
|
1328
|
-
const isVisible = isElementVisible(n2);
|
|
1329
|
-
const isInteractive = isElementInteractive(n2);
|
|
1330
1358
|
return {
|
|
1331
1359
|
type: NodeType$3.Element,
|
|
1332
1360
|
tagName,
|
|
@@ -1335,10 +1363,7 @@ function serializeElementNode(n2, options) {
|
|
|
1335
1363
|
isSVG: isSVGElement(n2) || void 0,
|
|
1336
1364
|
needBlock,
|
|
1337
1365
|
rootId,
|
|
1338
|
-
isCustom: isCustomElement
|
|
1339
|
-
isVisible,
|
|
1340
|
-
isInteractive,
|
|
1341
|
-
xPath
|
|
1366
|
+
isCustom: isCustomElement
|
|
1342
1367
|
};
|
|
1343
1368
|
}
|
|
1344
1369
|
function lowerIfExists(maybeAttr) {
|
|
@@ -1389,7 +1414,6 @@ function serializeNodeWithId(n2, options) {
|
|
|
1389
1414
|
maskTextClass,
|
|
1390
1415
|
maskTextSelector,
|
|
1391
1416
|
excludeAttribute,
|
|
1392
|
-
includeAttribute,
|
|
1393
1417
|
skipChild = false,
|
|
1394
1418
|
inlineStylesheet = true,
|
|
1395
1419
|
maskInputOptions = {},
|
|
@@ -1425,7 +1449,6 @@ function serializeNodeWithId(n2, options) {
|
|
|
1425
1449
|
blockClass,
|
|
1426
1450
|
blockSelector,
|
|
1427
1451
|
excludeAttribute,
|
|
1428
|
-
includeAttribute,
|
|
1429
1452
|
needsMask,
|
|
1430
1453
|
inlineStylesheet,
|
|
1431
1454
|
maskInputOptions,
|
|
@@ -1451,6 +1474,22 @@ function serializeNodeWithId(n2, options) {
|
|
|
1451
1474
|
id = genId();
|
|
1452
1475
|
}
|
|
1453
1476
|
const serializedNode = Object.assign(_serializedNode, { id });
|
|
1477
|
+
if (isElement(n2) || n2.nodeType === Node.TEXT_NODE) {
|
|
1478
|
+
serializedNode.xpath = buildXPath(n2);
|
|
1479
|
+
if (isElement(n2)) {
|
|
1480
|
+
const selector = buildSelector(n2);
|
|
1481
|
+
if (selector) {
|
|
1482
|
+
serializedNode.selector = selector;
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
if (n2.nodeType === Node.TEXT_NODE) {
|
|
1486
|
+
serializedNode.isVisible = isTextVisible(n2);
|
|
1487
|
+
}
|
|
1488
|
+
if (n2.nodeType === Node.ELEMENT_NODE) {
|
|
1489
|
+
serializedNode.isVisible = isElementVisible(n2);
|
|
1490
|
+
serializedNode.isInteractive = isElementInteractive(n2);
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1454
1493
|
mirror2.add(n2, serializedNode);
|
|
1455
1494
|
if (id === IGNORED_NODE) {
|
|
1456
1495
|
return null;
|
|
@@ -1479,7 +1518,6 @@ function serializeNodeWithId(n2, options) {
|
|
|
1479
1518
|
maskTextClass,
|
|
1480
1519
|
maskTextSelector,
|
|
1481
1520
|
excludeAttribute,
|
|
1482
|
-
includeAttribute,
|
|
1483
1521
|
skipChild,
|
|
1484
1522
|
inlineStylesheet,
|
|
1485
1523
|
maskInputOptions,
|
|
@@ -1540,7 +1578,6 @@ function serializeNodeWithId(n2, options) {
|
|
|
1540
1578
|
maskTextClass,
|
|
1541
1579
|
maskTextSelector,
|
|
1542
1580
|
excludeAttribute,
|
|
1543
|
-
includeAttribute,
|
|
1544
1581
|
skipChild: false,
|
|
1545
1582
|
inlineStylesheet,
|
|
1546
1583
|
maskInputOptions,
|
|
@@ -1583,7 +1620,6 @@ function serializeNodeWithId(n2, options) {
|
|
|
1583
1620
|
maskTextClass,
|
|
1584
1621
|
maskTextSelector,
|
|
1585
1622
|
excludeAttribute,
|
|
1586
|
-
includeAttribute,
|
|
1587
1623
|
skipChild: false,
|
|
1588
1624
|
inlineStylesheet,
|
|
1589
1625
|
maskInputOptions,
|
|
@@ -1621,8 +1657,7 @@ function snapshot(n2, options) {
|
|
|
1621
1657
|
blockSelector = null,
|
|
1622
1658
|
maskTextClass = "rr-mask",
|
|
1623
1659
|
maskTextSelector = null,
|
|
1624
|
-
excludeAttribute =
|
|
1625
|
-
includeAttribute = /.+/i,
|
|
1660
|
+
excludeAttribute = /.^/,
|
|
1626
1661
|
inlineStylesheet = true,
|
|
1627
1662
|
inlineImages = false,
|
|
1628
1663
|
recordCanvas = false,
|
|
@@ -1683,7 +1718,6 @@ function snapshot(n2, options) {
|
|
|
1683
1718
|
maskTextClass,
|
|
1684
1719
|
maskTextSelector,
|
|
1685
1720
|
excludeAttribute,
|
|
1686
|
-
includeAttribute,
|
|
1687
1721
|
skipChild: false,
|
|
1688
1722
|
inlineStylesheet,
|
|
1689
1723
|
maskInputOptions,
|
|
@@ -9094,6 +9128,41 @@ function patch(source, name, replacement) {
|
|
|
9094
9128
|
};
|
|
9095
9129
|
}
|
|
9096
9130
|
}
|
|
9131
|
+
function describeNode(el) {
|
|
9132
|
+
const tag = el.tagName.toLowerCase();
|
|
9133
|
+
const id = el.id ? `#${el.id}` : "";
|
|
9134
|
+
const classes = el.classList.length ? "." + Array.from(el.classList).join(".") : "";
|
|
9135
|
+
return `${tag}${id}${classes}`;
|
|
9136
|
+
}
|
|
9137
|
+
function getElementVisibility(el) {
|
|
9138
|
+
var _a2, _b;
|
|
9139
|
+
const win = ((_a2 = el.ownerDocument) == null ? void 0 : _a2.defaultView) ?? window;
|
|
9140
|
+
const rect = el.getBoundingClientRect();
|
|
9141
|
+
const viewportWidth = win.innerWidth || win.document.documentElement.clientWidth || 0;
|
|
9142
|
+
const viewportHeight = win.innerHeight || win.document.documentElement.clientHeight || 0;
|
|
9143
|
+
const isRectVisible = rect.width > 0 && rect.height > 0 && rect.bottom > 0 && rect.right > 0 && rect.top < viewportHeight && rect.left < viewportWidth;
|
|
9144
|
+
const style = (_b = win.getComputedStyle) == null ? void 0 : _b.call(win, el);
|
|
9145
|
+
const isStyleVisible2 = !!style && style.display !== "none" && style.visibility !== "hidden" && (parseFloat(style.opacity) || 0) > 0;
|
|
9146
|
+
const isVisible = isStyleVisible2 && isRectVisible;
|
|
9147
|
+
let ratio = 0;
|
|
9148
|
+
if (isVisible) {
|
|
9149
|
+
const xOverlap = Math.max(
|
|
9150
|
+
0,
|
|
9151
|
+
Math.min(rect.right, viewportWidth) - Math.max(rect.left, 0)
|
|
9152
|
+
);
|
|
9153
|
+
const yOverlap = Math.max(
|
|
9154
|
+
0,
|
|
9155
|
+
Math.min(rect.bottom, viewportHeight) - Math.max(rect.top, 0)
|
|
9156
|
+
);
|
|
9157
|
+
const intersectionArea = xOverlap * yOverlap;
|
|
9158
|
+
const elementArea = rect.width * rect.height;
|
|
9159
|
+
ratio = elementArea > 0 ? intersectionArea / elementArea : 0;
|
|
9160
|
+
}
|
|
9161
|
+
return {
|
|
9162
|
+
isVisible,
|
|
9163
|
+
ratio
|
|
9164
|
+
};
|
|
9165
|
+
}
|
|
9097
9166
|
const index = {
|
|
9098
9167
|
childNodes,
|
|
9099
9168
|
parentNode,
|
|
@@ -9107,7 +9176,9 @@ const index = {
|
|
|
9107
9176
|
querySelector,
|
|
9108
9177
|
querySelectorAll,
|
|
9109
9178
|
mutationObserver: mutationObserverCtor,
|
|
9110
|
-
patch
|
|
9179
|
+
patch,
|
|
9180
|
+
describeNode,
|
|
9181
|
+
getElementVisibility
|
|
9111
9182
|
};
|
|
9112
9183
|
function on(type, fn, target = document) {
|
|
9113
9184
|
const options = { capture: true, passive: true };
|
|
@@ -9381,6 +9452,7 @@ var IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {
|
|
|
9381
9452
|
IncrementalSource2[IncrementalSource2["Selection"] = 14] = "Selection";
|
|
9382
9453
|
IncrementalSource2[IncrementalSource2["AdoptedStyleSheet"] = 15] = "AdoptedStyleSheet";
|
|
9383
9454
|
IncrementalSource2[IncrementalSource2["CustomElement"] = 16] = "CustomElement";
|
|
9455
|
+
IncrementalSource2[IncrementalSource2["VisibilityMutation"] = 17] = "VisibilityMutation";
|
|
9384
9456
|
return IncrementalSource2;
|
|
9385
9457
|
})(IncrementalSource || {});
|
|
9386
9458
|
var MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {
|
|
@@ -9527,7 +9599,6 @@ class MutationBuffer {
|
|
|
9527
9599
|
__publicField(this, "maskTextClass");
|
|
9528
9600
|
__publicField(this, "maskTextSelector");
|
|
9529
9601
|
__publicField(this, "excludeAttribute");
|
|
9530
|
-
__publicField(this, "includeAttribute");
|
|
9531
9602
|
__publicField(this, "inlineStylesheet");
|
|
9532
9603
|
__publicField(this, "maskInputOptions");
|
|
9533
9604
|
__publicField(this, "maskTextFn");
|
|
@@ -9543,6 +9614,7 @@ class MutationBuffer {
|
|
|
9543
9614
|
__publicField(this, "stylesheetManager");
|
|
9544
9615
|
__publicField(this, "shadowDomManager");
|
|
9545
9616
|
__publicField(this, "canvasManager");
|
|
9617
|
+
__publicField(this, "visibilityManager");
|
|
9546
9618
|
__publicField(this, "processedNodeManager");
|
|
9547
9619
|
__publicField(this, "unattachedDoc");
|
|
9548
9620
|
__publicField(this, "processMutations", (mutations) => {
|
|
@@ -9592,7 +9664,6 @@ class MutationBuffer {
|
|
|
9592
9664
|
maskTextClass: this.maskTextClass,
|
|
9593
9665
|
maskTextSelector: this.maskTextSelector,
|
|
9594
9666
|
excludeAttribute: this.excludeAttribute,
|
|
9595
|
-
includeAttribute: this.includeAttribute,
|
|
9596
9667
|
skipChild: true,
|
|
9597
9668
|
newlyAddedElement: true,
|
|
9598
9669
|
inlineStylesheet: this.inlineStylesheet,
|
|
@@ -9638,7 +9709,8 @@ class MutationBuffer {
|
|
|
9638
9709
|
this.mirror.removeNodeFromMap(this.mapRemoves.shift());
|
|
9639
9710
|
}
|
|
9640
9711
|
for (const n2 of this.movedSet) {
|
|
9641
|
-
if (isParentRemoved(this.removesSubTreeCache, n2, this.mirror) &&
|
|
9712
|
+
if (isParentRemoved(this.removesSubTreeCache, n2, this.mirror) && // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
9713
|
+
!this.movedSet.has(index.parentNode(n2))) {
|
|
9642
9714
|
continue;
|
|
9643
9715
|
}
|
|
9644
9716
|
pushAdd(n2);
|
|
@@ -9794,12 +9866,60 @@ class MutationBuffer {
|
|
|
9794
9866
|
const target = m.target;
|
|
9795
9867
|
let attributeName = m.attributeName;
|
|
9796
9868
|
let value = m.target.getAttribute(attributeName);
|
|
9797
|
-
const
|
|
9798
|
-
const
|
|
9869
|
+
const attrKey = attributeName;
|
|
9870
|
+
const propValue = target[attrKey];
|
|
9871
|
+
const isBooleanAttr = typeof propValue === "boolean";
|
|
9872
|
+
const inDOM = document.contains(target);
|
|
9873
|
+
const isVisible = isElementVisible(target);
|
|
9874
|
+
const isExcludeAttributeName = isExcludeAttribute(attributeName, this.excludeAttribute);
|
|
9875
|
+
const isPhantomAttributeMutation = value === null && // текущего атрибута нет
|
|
9876
|
+
!target.hasAttribute(attributeName) && // явно подтверждаем отсутствие
|
|
9877
|
+
m.oldValue !== null && // раньше он был
|
|
9878
|
+
(propValue === "" || // свойство = пустая строка
|
|
9879
|
+
propValue === null || // или null
|
|
9880
|
+
typeof propValue === "undefined");
|
|
9799
9881
|
if (isPhantomAttributeMutation) {
|
|
9882
|
+
console.debug(
|
|
9883
|
+
`[${nowTimestamp()}] [rrweb:record/mutation] ⛔ phantom attribute mutation ignored`,
|
|
9884
|
+
{
|
|
9885
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
|
9886
|
+
node: index.describeNode(target),
|
|
9887
|
+
tag: target.tagName,
|
|
9888
|
+
nodeType: target.nodeType,
|
|
9889
|
+
attribute: attributeName,
|
|
9890
|
+
value,
|
|
9891
|
+
oldValue: m.oldValue,
|
|
9892
|
+
excludeAttribute: this.excludeAttribute,
|
|
9893
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
9894
|
+
propValue,
|
|
9895
|
+
isBooleanAttr,
|
|
9896
|
+
inDOM,
|
|
9897
|
+
isVisible,
|
|
9898
|
+
isExcludeAttributeName
|
|
9899
|
+
}
|
|
9900
|
+
);
|
|
9800
9901
|
return;
|
|
9801
9902
|
}
|
|
9802
9903
|
if (isExcludeAttribute(attributeName, this.excludeAttribute)) {
|
|
9904
|
+
console.debug(
|
|
9905
|
+
`[${nowTimestamp()}] [rrweb:record/mutation] ⛔ excluded attribute mutation ignored`,
|
|
9906
|
+
{
|
|
9907
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
|
9908
|
+
node: index.describeNode(target),
|
|
9909
|
+
tag: target.tagName,
|
|
9910
|
+
nodeType: target.nodeType,
|
|
9911
|
+
attribute: attributeName,
|
|
9912
|
+
value,
|
|
9913
|
+
oldValue: m.oldValue,
|
|
9914
|
+
excludeAttribute: this.excludeAttribute,
|
|
9915
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
9916
|
+
propValue,
|
|
9917
|
+
isBooleanAttr,
|
|
9918
|
+
inDOM,
|
|
9919
|
+
isVisible,
|
|
9920
|
+
isExcludeAttributeName
|
|
9921
|
+
}
|
|
9922
|
+
);
|
|
9803
9923
|
return;
|
|
9804
9924
|
}
|
|
9805
9925
|
if (attributeName === "value") {
|
|
@@ -9844,9 +9964,35 @@ class MutationBuffer {
|
|
|
9844
9964
|
toLowerCase(attributeName),
|
|
9845
9965
|
value
|
|
9846
9966
|
);
|
|
9847
|
-
|
|
9848
|
-
|
|
9849
|
-
|
|
9967
|
+
const isSuspiciousClassMutation = attributeName !== "class" && (m.oldValue === null || // ранее не было класса
|
|
9968
|
+
value === "" || // класс удалён
|
|
9969
|
+
value !== m.oldValue);
|
|
9970
|
+
if (isSuspiciousClassMutation) {
|
|
9971
|
+
console.debug(
|
|
9972
|
+
`[${nowTimestamp()}] [rrweb:record/mutation] ⚠️ suspicious attribute mutation`,
|
|
9973
|
+
{
|
|
9974
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
|
9975
|
+
reason: [
|
|
9976
|
+
value === m.oldValue ? "no change in value" : null,
|
|
9977
|
+
value === propValue ? "mirrored in DOM property" : null,
|
|
9978
|
+
value === item.attributes[attributeName] ? "redundant assignment" : null
|
|
9979
|
+
].filter(Boolean).join(", ") || "uncategorized",
|
|
9980
|
+
node: index.describeNode(target),
|
|
9981
|
+
tag: target.tagName,
|
|
9982
|
+
nodeType: target.nodeType,
|
|
9983
|
+
attribute: attributeName,
|
|
9984
|
+
value,
|
|
9985
|
+
oldValue: m.oldValue,
|
|
9986
|
+
transformedValue: item.attributes[attributeName],
|
|
9987
|
+
excludeAttribute: this.excludeAttribute,
|
|
9988
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
9989
|
+
propValue,
|
|
9990
|
+
isBooleanAttr,
|
|
9991
|
+
inDOM,
|
|
9992
|
+
isVisible,
|
|
9993
|
+
isExcludeAttributeName
|
|
9994
|
+
}
|
|
9995
|
+
);
|
|
9850
9996
|
}
|
|
9851
9997
|
if (attributeName === "style") {
|
|
9852
9998
|
if (!this.unattachedDoc) {
|
|
@@ -9961,7 +10107,6 @@ class MutationBuffer {
|
|
|
9961
10107
|
"maskTextClass",
|
|
9962
10108
|
"maskTextSelector",
|
|
9963
10109
|
"excludeAttribute",
|
|
9964
|
-
"includeAttribute",
|
|
9965
10110
|
"inlineStylesheet",
|
|
9966
10111
|
"maskInputOptions",
|
|
9967
10112
|
"maskTextFn",
|
|
@@ -9977,6 +10122,7 @@ class MutationBuffer {
|
|
|
9977
10122
|
"stylesheetManager",
|
|
9978
10123
|
"shadowDomManager",
|
|
9979
10124
|
"canvasManager",
|
|
10125
|
+
"visibilityManager",
|
|
9980
10126
|
"processedNodeManager"
|
|
9981
10127
|
].forEach((key) => {
|
|
9982
10128
|
this[key] = options[key];
|
|
@@ -9985,10 +10131,12 @@ class MutationBuffer {
|
|
|
9985
10131
|
freeze() {
|
|
9986
10132
|
this.frozen = true;
|
|
9987
10133
|
this.canvasManager.freeze();
|
|
10134
|
+
this.visibilityManager.freeze();
|
|
9988
10135
|
}
|
|
9989
10136
|
unfreeze() {
|
|
9990
10137
|
this.frozen = false;
|
|
9991
10138
|
this.canvasManager.unfreeze();
|
|
10139
|
+
this.visibilityManager.unfreeze();
|
|
9992
10140
|
this.emit();
|
|
9993
10141
|
}
|
|
9994
10142
|
isFrozen() {
|
|
@@ -9997,15 +10145,18 @@ class MutationBuffer {
|
|
|
9997
10145
|
lock() {
|
|
9998
10146
|
this.locked = true;
|
|
9999
10147
|
this.canvasManager.lock();
|
|
10148
|
+
this.visibilityManager.lock();
|
|
10000
10149
|
}
|
|
10001
10150
|
unlock() {
|
|
10002
10151
|
this.locked = false;
|
|
10003
10152
|
this.canvasManager.unlock();
|
|
10153
|
+
this.visibilityManager.unlock();
|
|
10004
10154
|
this.emit();
|
|
10005
10155
|
}
|
|
10006
10156
|
reset() {
|
|
10007
10157
|
this.shadowDomManager.reset();
|
|
10008
10158
|
this.canvasManager.reset();
|
|
10159
|
+
this.visibilityManager.reset();
|
|
10009
10160
|
}
|
|
10010
10161
|
}
|
|
10011
10162
|
function deepDelete(addsSet, n2) {
|
|
@@ -10939,6 +11090,7 @@ function mergeHooks(o2, hooks) {
|
|
|
10939
11090
|
styleSheetRuleCb,
|
|
10940
11091
|
styleDeclarationCb,
|
|
10941
11092
|
canvasMutationCb,
|
|
11093
|
+
visibilityMutationCb,
|
|
10942
11094
|
fontCb,
|
|
10943
11095
|
selectionCb,
|
|
10944
11096
|
customElementCb
|
|
@@ -11003,6 +11155,12 @@ function mergeHooks(o2, hooks) {
|
|
|
11003
11155
|
}
|
|
11004
11156
|
canvasMutationCb(...p);
|
|
11005
11157
|
};
|
|
11158
|
+
o2.visibilityMutationCb = (...p) => {
|
|
11159
|
+
if (hooks.visibilityMutation) {
|
|
11160
|
+
hooks.visibilityMutation(...p);
|
|
11161
|
+
}
|
|
11162
|
+
visibilityMutationCb(...p);
|
|
11163
|
+
};
|
|
11006
11164
|
o2.fontCb = (...p) => {
|
|
11007
11165
|
if (hooks.font) {
|
|
11008
11166
|
hooks.font(...p);
|
|
@@ -12116,11 +12274,249 @@ class ProcessedNodeManager {
|
|
|
12116
12274
|
destroy() {
|
|
12117
12275
|
}
|
|
12118
12276
|
}
|
|
12277
|
+
function computeVisibility(elements, previous, options) {
|
|
12278
|
+
const root2 = (options == null ? void 0 : options.root) ?? null;
|
|
12279
|
+
const threshold = (options == null ? void 0 : options.threshold) ?? 0.5;
|
|
12280
|
+
const sensitivity = (options == null ? void 0 : options.sensitivity) ?? 0.05;
|
|
12281
|
+
const rootMarginFn = parseRootMargin((options == null ? void 0 : options.rootMargin) ?? "0px");
|
|
12282
|
+
const current = /* @__PURE__ */ new Map();
|
|
12283
|
+
const rootRect = getRootRect(root2);
|
|
12284
|
+
const expandedRoot = expandRootRect(rootRect, rootMarginFn);
|
|
12285
|
+
for (const el of elements) {
|
|
12286
|
+
const elRect = el.getBoundingClientRect();
|
|
12287
|
+
let intersectionRect = emptyRect();
|
|
12288
|
+
let intersectionRatio = 0;
|
|
12289
|
+
if (elRect.width > 0 && elRect.height > 0) {
|
|
12290
|
+
intersectionRect = computeIntersectionRect(elRect, expandedRoot);
|
|
12291
|
+
intersectionRatio = computeIntersectionRatio(elRect, intersectionRect);
|
|
12292
|
+
intersectionRatio = Math.round(intersectionRatio * 100) / 100;
|
|
12293
|
+
}
|
|
12294
|
+
const isStyle = isStyleVisible(el);
|
|
12295
|
+
const old = previous.get(el) ?? null;
|
|
12296
|
+
const prevRatio = (old == null ? void 0 : old.intersectionRatio) ?? 0;
|
|
12297
|
+
const currRatio = intersectionRatio;
|
|
12298
|
+
const wasVisible = (old == null ? void 0 : old.isStyleVisible) && prevRatio > threshold;
|
|
12299
|
+
const nowVisible = isStyle && currRatio > threshold;
|
|
12300
|
+
const changed = !old || wasVisible !== nowVisible || wasVisible !== nowVisible && Math.abs(currRatio - prevRatio) > sensitivity;
|
|
12301
|
+
if (changed) {
|
|
12302
|
+
current.set(el, {
|
|
12303
|
+
target: el,
|
|
12304
|
+
isVisible: nowVisible,
|
|
12305
|
+
isStyleVisible: isStyle,
|
|
12306
|
+
intersectionRatio: currRatio,
|
|
12307
|
+
intersectionRect,
|
|
12308
|
+
oldValue: old
|
|
12309
|
+
});
|
|
12310
|
+
} else {
|
|
12311
|
+
current.set(el, old);
|
|
12312
|
+
}
|
|
12313
|
+
}
|
|
12314
|
+
return current;
|
|
12315
|
+
}
|
|
12316
|
+
function parseRootMargin(marginStr) {
|
|
12317
|
+
const parts = marginStr.trim().split(/\s+/);
|
|
12318
|
+
const getValue = (val, size) => val.endsWith("%") ? parseFloat(val) / 100 * size : parseFloat(val) || 0;
|
|
12319
|
+
return function(rootRect) {
|
|
12320
|
+
const top = getValue(parts[0] || "0px", rootRect.height);
|
|
12321
|
+
const right = getValue(parts[1] || parts[0] || "0px", rootRect.width);
|
|
12322
|
+
const bottom = getValue(parts[2] || parts[0] || "0px", rootRect.height);
|
|
12323
|
+
const left = getValue(parts[3] || parts[1] || parts[0] || "0px", rootRect.width);
|
|
12324
|
+
return { top, right, bottom, left, width: 0, height: 0 };
|
|
12325
|
+
};
|
|
12326
|
+
}
|
|
12327
|
+
function getRootRect(root2) {
|
|
12328
|
+
return root2 ? root2.getBoundingClientRect() : new DOMRect(0, 0, window.innerWidth, window.innerHeight);
|
|
12329
|
+
}
|
|
12330
|
+
function expandRootRect(rect, marginFn) {
|
|
12331
|
+
const margin = marginFn(rect);
|
|
12332
|
+
return new DOMRect(
|
|
12333
|
+
rect.left - margin.left,
|
|
12334
|
+
rect.top - margin.top,
|
|
12335
|
+
rect.width + margin.left + margin.right,
|
|
12336
|
+
rect.height + margin.top + margin.bottom
|
|
12337
|
+
);
|
|
12338
|
+
}
|
|
12339
|
+
function computeIntersectionRect(a2, b) {
|
|
12340
|
+
const top = Math.max(a2.top, b.top);
|
|
12341
|
+
const left = Math.max(a2.left, b.left);
|
|
12342
|
+
const bottom = Math.min(a2.bottom, b.bottom);
|
|
12343
|
+
const right = Math.min(a2.right, b.right);
|
|
12344
|
+
const width = Math.max(0, right - left);
|
|
12345
|
+
const height = Math.max(0, bottom - top);
|
|
12346
|
+
return { top, left, bottom, right, width, height };
|
|
12347
|
+
}
|
|
12348
|
+
function computeIntersectionRatio(elRect, intersectionRect) {
|
|
12349
|
+
const elArea = elRect.width * elRect.height;
|
|
12350
|
+
const intArea = intersectionRect.width * intersectionRect.height;
|
|
12351
|
+
return elArea > 0 ? intArea / elArea : 0;
|
|
12352
|
+
}
|
|
12353
|
+
function emptyRect() {
|
|
12354
|
+
return { top: 0, left: 0, right: 0, bottom: 0, width: 0, height: 0 };
|
|
12355
|
+
}
|
|
12356
|
+
function isStyleVisible(el) {
|
|
12357
|
+
const style = getComputedStyle(el);
|
|
12358
|
+
return style && style.display !== "none" && style.visibility !== "hidden" && parseFloat(style.opacity || "1") > 0;
|
|
12359
|
+
}
|
|
12360
|
+
class VisibilityManager {
|
|
12361
|
+
constructor(options) {
|
|
12362
|
+
__publicField(this, "frozen", false);
|
|
12363
|
+
__publicField(this, "locked", false);
|
|
12364
|
+
__publicField(this, "pending", /* @__PURE__ */ new Map());
|
|
12365
|
+
__publicField(this, "mirror");
|
|
12366
|
+
__publicField(this, "mutationCb");
|
|
12367
|
+
__publicField(this, "rafId", null);
|
|
12368
|
+
__publicField(this, "rafThrottle");
|
|
12369
|
+
__publicField(this, "lastFlushTime", 0);
|
|
12370
|
+
__publicField(this, "elements", /* @__PURE__ */ new Set());
|
|
12371
|
+
__publicField(this, "previousState", /* @__PURE__ */ new Map());
|
|
12372
|
+
__publicField(this, "root", null);
|
|
12373
|
+
__publicField(this, "threshold");
|
|
12374
|
+
__publicField(this, "sensitivity");
|
|
12375
|
+
__publicField(this, "rootMargin");
|
|
12376
|
+
__publicField(this, "hasInitialized", false);
|
|
12377
|
+
__publicField(this, "mode", "none");
|
|
12378
|
+
__publicField(this, "debounce", 50);
|
|
12379
|
+
__publicField(this, "throttle", 100);
|
|
12380
|
+
__publicField(this, "buffer", /* @__PURE__ */ new Map());
|
|
12381
|
+
__publicField(this, "debounceTimer", null);
|
|
12382
|
+
__publicField(this, "lastThrottleTime", 0);
|
|
12383
|
+
__publicField(this, "disabled", false);
|
|
12384
|
+
__publicField(this, "notifyActivity");
|
|
12385
|
+
const { doc, mirror: mirror2, sampling, mutationCb, notifyActivity } = options;
|
|
12386
|
+
this.mirror = mirror2;
|
|
12387
|
+
this.mutationCb = mutationCb;
|
|
12388
|
+
this.notifyActivity = notifyActivity;
|
|
12389
|
+
this.rootMargin = "0px";
|
|
12390
|
+
if (sampling === false) {
|
|
12391
|
+
this.disabled = true;
|
|
12392
|
+
return;
|
|
12393
|
+
}
|
|
12394
|
+
const visibilitySampling = typeof sampling === "object" && sampling !== null ? sampling : {};
|
|
12395
|
+
this.mode = (visibilitySampling == null ? void 0 : visibilitySampling.mode) ?? "none";
|
|
12396
|
+
this.debounce = Number((visibilitySampling == null ? void 0 : visibilitySampling.debounce) ?? 100);
|
|
12397
|
+
this.throttle = Number((visibilitySampling == null ? void 0 : visibilitySampling.throttle) ?? 100);
|
|
12398
|
+
this.threshold = Number((visibilitySampling == null ? void 0 : visibilitySampling.threshold) ?? 0.5);
|
|
12399
|
+
this.sensitivity = Number((visibilitySampling == null ? void 0 : visibilitySampling.sensitivity) ?? 0.05);
|
|
12400
|
+
this.rafThrottle = Number((visibilitySampling == null ? void 0 : visibilitySampling.rafThrottle) ?? 100);
|
|
12401
|
+
doc.querySelectorAll("*").forEach((el) => this.observe(el));
|
|
12402
|
+
const mo = new MutationObserver((mutations) => {
|
|
12403
|
+
mutations.forEach((m) => {
|
|
12404
|
+
m.addedNodes.forEach((n2) => {
|
|
12405
|
+
if (n2.nodeType === Node.ELEMENT_NODE) {
|
|
12406
|
+
this.observe(n2);
|
|
12407
|
+
n2.querySelectorAll("*").forEach((el) => this.observe(el));
|
|
12408
|
+
}
|
|
12409
|
+
});
|
|
12410
|
+
m.removedNodes.forEach((n2) => {
|
|
12411
|
+
if (n2.nodeType === Node.ELEMENT_NODE) {
|
|
12412
|
+
this.unobserve(n2);
|
|
12413
|
+
}
|
|
12414
|
+
});
|
|
12415
|
+
});
|
|
12416
|
+
});
|
|
12417
|
+
mo.observe(doc.body, { childList: true, subtree: true });
|
|
12418
|
+
this.startPendingFlushLoop();
|
|
12419
|
+
}
|
|
12420
|
+
startPendingFlushLoop() {
|
|
12421
|
+
if (this.disabled) return;
|
|
12422
|
+
const loop = (timestamp) => {
|
|
12423
|
+
if (timestamp - this.lastFlushTime >= this.rafThrottle) {
|
|
12424
|
+
this.lastFlushTime = timestamp;
|
|
12425
|
+
this.flushPendingVisibilityMutations();
|
|
12426
|
+
}
|
|
12427
|
+
this.rafId = requestAnimationFrame(loop);
|
|
12428
|
+
};
|
|
12429
|
+
this.rafId = requestAnimationFrame(loop);
|
|
12430
|
+
}
|
|
12431
|
+
flushPendingVisibilityMutations() {
|
|
12432
|
+
if (this.disabled) return;
|
|
12433
|
+
if (this.frozen || this.locked || this.elements.size === 0) return;
|
|
12434
|
+
const state = computeVisibility(this.elements, this.previousState, {
|
|
12435
|
+
root: this.root,
|
|
12436
|
+
threshold: this.threshold,
|
|
12437
|
+
sensitivity: this.sensitivity,
|
|
12438
|
+
rootMargin: this.rootMargin
|
|
12439
|
+
});
|
|
12440
|
+
for (const [el, entry] of state.entries()) {
|
|
12441
|
+
const old = this.previousState.get(el);
|
|
12442
|
+
const changed = !old || old.isVisible !== entry.isVisible || Math.abs(old.intersectionRatio - entry.intersectionRatio) > this.sensitivity;
|
|
12443
|
+
if (changed) {
|
|
12444
|
+
const id = this.mirror.getId(el);
|
|
12445
|
+
if (id !== -1) {
|
|
12446
|
+
this.buffer.set(el, {
|
|
12447
|
+
id,
|
|
12448
|
+
isVisible: entry.isVisible,
|
|
12449
|
+
ratio: entry.intersectionRatio
|
|
12450
|
+
});
|
|
12451
|
+
}
|
|
12452
|
+
this.previousState.set(el, entry);
|
|
12453
|
+
}
|
|
12454
|
+
}
|
|
12455
|
+
this.previousState = state;
|
|
12456
|
+
if (!this.hasInitialized) {
|
|
12457
|
+
this.hasInitialized = true;
|
|
12458
|
+
this.buffer.clear();
|
|
12459
|
+
return;
|
|
12460
|
+
}
|
|
12461
|
+
this.scheduleEmit();
|
|
12462
|
+
}
|
|
12463
|
+
scheduleEmit() {
|
|
12464
|
+
if (this.mode === "debounce") {
|
|
12465
|
+
clearTimeout(this.debounceTimer);
|
|
12466
|
+
this.debounceTimer = setTimeout(() => this.flushBuffer(), this.debounce);
|
|
12467
|
+
} else if (this.mode === "throttle") {
|
|
12468
|
+
const now = performance.now();
|
|
12469
|
+
if (now - this.lastThrottleTime >= this.throttle) {
|
|
12470
|
+
this.lastThrottleTime = now;
|
|
12471
|
+
this.flushBuffer();
|
|
12472
|
+
}
|
|
12473
|
+
} else {
|
|
12474
|
+
this.flushBuffer();
|
|
12475
|
+
}
|
|
12476
|
+
}
|
|
12477
|
+
flushBuffer() {
|
|
12478
|
+
var _a2;
|
|
12479
|
+
if (this.buffer.size === 0) return;
|
|
12480
|
+
(_a2 = this.notifyActivity) == null ? void 0 : _a2.call(this, this.buffer.size);
|
|
12481
|
+
this.mutationCb({ mutations: Array.from(this.buffer.values()) });
|
|
12482
|
+
this.buffer.clear();
|
|
12483
|
+
}
|
|
12484
|
+
observe(el) {
|
|
12485
|
+
if (this.disabled) return;
|
|
12486
|
+
this.elements.add(el);
|
|
12487
|
+
}
|
|
12488
|
+
unobserve(el) {
|
|
12489
|
+
if (this.disabled) return;
|
|
12490
|
+
this.elements.delete(el);
|
|
12491
|
+
this.previousState.delete(el);
|
|
12492
|
+
this.pending.delete(el);
|
|
12493
|
+
}
|
|
12494
|
+
freeze() {
|
|
12495
|
+
this.frozen = true;
|
|
12496
|
+
}
|
|
12497
|
+
unfreeze() {
|
|
12498
|
+
this.frozen = false;
|
|
12499
|
+
}
|
|
12500
|
+
lock() {
|
|
12501
|
+
this.locked = true;
|
|
12502
|
+
}
|
|
12503
|
+
unlock() {
|
|
12504
|
+
this.locked = false;
|
|
12505
|
+
}
|
|
12506
|
+
reset() {
|
|
12507
|
+
this.elements.clear();
|
|
12508
|
+
this.previousState.clear();
|
|
12509
|
+
this.pending.clear();
|
|
12510
|
+
if (this.rafId) cancelAnimationFrame(this.rafId);
|
|
12511
|
+
}
|
|
12512
|
+
}
|
|
12119
12513
|
let wrappedEmit;
|
|
12120
12514
|
let takeFullSnapshot$1;
|
|
12121
12515
|
let canvasManager;
|
|
12516
|
+
let visibilityManager;
|
|
12122
12517
|
let recording = false;
|
|
12123
|
-
const
|
|
12518
|
+
const customEventQueue = [];
|
|
12519
|
+
let flushCustomEventQueue;
|
|
12124
12520
|
try {
|
|
12125
12521
|
if (Array.from([1], (x2) => x2 * 2)[0] !== 2) {
|
|
12126
12522
|
const cleanFrame = document.createElement("iframe");
|
|
@@ -12137,12 +12533,12 @@ function record(options = {}) {
|
|
|
12137
12533
|
emit,
|
|
12138
12534
|
checkoutEveryNms,
|
|
12139
12535
|
checkoutEveryNth,
|
|
12536
|
+
checkoutEveryNvm,
|
|
12140
12537
|
blockClass = "rr-block",
|
|
12141
12538
|
blockSelector = null,
|
|
12142
12539
|
ignoreClass = "rr-ignore",
|
|
12143
12540
|
ignoreSelector = null,
|
|
12144
12541
|
excludeAttribute: _excludeAttribute,
|
|
12145
|
-
includeAttribute: _includeAttribute,
|
|
12146
12542
|
maskTextClass = "rr-mask",
|
|
12147
12543
|
maskTextSelector = null,
|
|
12148
12544
|
inlineStylesheet = true,
|
|
@@ -12160,7 +12556,7 @@ function record(options = {}) {
|
|
|
12160
12556
|
recordCanvas = false,
|
|
12161
12557
|
recordCrossOriginIframes = false,
|
|
12162
12558
|
recordAfter = options.recordAfter === "DOMContentLoaded" ? options.recordAfter : "load",
|
|
12163
|
-
|
|
12559
|
+
flushCustomEvent = options.flushCustomEvent !== void 0 ? options.flushCustomEvent : "after",
|
|
12164
12560
|
userTriggeredOnInput = false,
|
|
12165
12561
|
collectFonts = false,
|
|
12166
12562
|
inlineImages = false,
|
|
@@ -12192,8 +12588,7 @@ function record(options = {}) {
|
|
|
12192
12588
|
sampling.mousemove = mousemoveWait;
|
|
12193
12589
|
}
|
|
12194
12590
|
mirror.reset();
|
|
12195
|
-
const excludeAttribute = _excludeAttribute === void 0 ?
|
|
12196
|
-
const includeAttribute = _includeAttribute === void 0 ? /.+/i : _includeAttribute;
|
|
12591
|
+
const excludeAttribute = _excludeAttribute === void 0 ? /.^/ : _excludeAttribute;
|
|
12197
12592
|
const maskInputOptions = maskAllInputs === true ? {
|
|
12198
12593
|
color: true,
|
|
12199
12594
|
date: true,
|
|
@@ -12230,6 +12625,10 @@ function record(options = {}) {
|
|
|
12230
12625
|
polyfill$1();
|
|
12231
12626
|
let lastFullSnapshotEvent;
|
|
12232
12627
|
let incrementalSnapshotCount = 0;
|
|
12628
|
+
let recentVisibilityChanges = 0;
|
|
12629
|
+
const onVisibilityActivity = (count) => {
|
|
12630
|
+
recentVisibilityChanges += count;
|
|
12631
|
+
};
|
|
12233
12632
|
const eventProcessor = (e2) => {
|
|
12234
12633
|
for (const plugin3 of plugins || []) {
|
|
12235
12634
|
if (plugin3.eventProcessor) {
|
|
@@ -12270,7 +12669,11 @@ function record(options = {}) {
|
|
|
12270
12669
|
incrementalSnapshotCount++;
|
|
12271
12670
|
const exceedCount = checkoutEveryNth && incrementalSnapshotCount >= checkoutEveryNth;
|
|
12272
12671
|
const exceedTime = checkoutEveryNms && e2.timestamp - lastFullSnapshotEvent.timestamp > checkoutEveryNms;
|
|
12273
|
-
|
|
12672
|
+
const exceedVisibility = checkoutEveryNvm && recentVisibilityChanges >= checkoutEveryNvm;
|
|
12673
|
+
if (exceedCount || exceedTime || exceedVisibility) {
|
|
12674
|
+
if (exceedVisibility) {
|
|
12675
|
+
recentVisibilityChanges = 0;
|
|
12676
|
+
}
|
|
12274
12677
|
takeFullSnapshot$1(true);
|
|
12275
12678
|
}
|
|
12276
12679
|
}
|
|
@@ -12298,6 +12701,17 @@ function record(options = {}) {
|
|
|
12298
12701
|
...p
|
|
12299
12702
|
}
|
|
12300
12703
|
});
|
|
12704
|
+
const wrappedVisibilityMutationEmit = (p) => {
|
|
12705
|
+
var _a2;
|
|
12706
|
+
(_a2 = hooks == null ? void 0 : hooks.visibilityMutation) == null ? void 0 : _a2.call(hooks, p);
|
|
12707
|
+
wrappedEmit({
|
|
12708
|
+
type: EventType.IncrementalSnapshot,
|
|
12709
|
+
data: {
|
|
12710
|
+
source: IncrementalSource.VisibilityMutation,
|
|
12711
|
+
...p
|
|
12712
|
+
}
|
|
12713
|
+
});
|
|
12714
|
+
};
|
|
12301
12715
|
const wrappedAdoptedStyleSheetEmit = (a2) => wrappedEmit({
|
|
12302
12716
|
type: EventType.IncrementalSnapshot,
|
|
12303
12717
|
data: {
|
|
@@ -12335,6 +12749,13 @@ function record(options = {}) {
|
|
|
12335
12749
|
sampling: sampling.canvas,
|
|
12336
12750
|
dataURLOptions
|
|
12337
12751
|
});
|
|
12752
|
+
visibilityManager = new VisibilityManager({
|
|
12753
|
+
doc: window.document,
|
|
12754
|
+
mirror,
|
|
12755
|
+
sampling: sampling.visibility,
|
|
12756
|
+
mutationCb: wrappedVisibilityMutationEmit,
|
|
12757
|
+
notifyActivity: onVisibilityActivity
|
|
12758
|
+
});
|
|
12338
12759
|
const shadowDomManager = new ShadowDomManager({
|
|
12339
12760
|
mutationCb: wrappedMutationEmit,
|
|
12340
12761
|
scrollCb: wrappedScrollEmit,
|
|
@@ -12344,7 +12765,6 @@ function record(options = {}) {
|
|
|
12344
12765
|
maskTextClass,
|
|
12345
12766
|
maskTextSelector,
|
|
12346
12767
|
excludeAttribute,
|
|
12347
|
-
includeAttribute,
|
|
12348
12768
|
inlineStylesheet,
|
|
12349
12769
|
maskInputOptions,
|
|
12350
12770
|
dataURLOptions,
|
|
@@ -12357,6 +12777,7 @@ function record(options = {}) {
|
|
|
12357
12777
|
iframeManager,
|
|
12358
12778
|
stylesheetManager,
|
|
12359
12779
|
canvasManager,
|
|
12780
|
+
visibilityManager,
|
|
12360
12781
|
keepIframeSrcFn,
|
|
12361
12782
|
processedNodeManager
|
|
12362
12783
|
},
|
|
@@ -12387,7 +12808,6 @@ function record(options = {}) {
|
|
|
12387
12808
|
maskTextClass,
|
|
12388
12809
|
maskTextSelector,
|
|
12389
12810
|
excludeAttribute,
|
|
12390
|
-
includeAttribute,
|
|
12391
12811
|
inlineStylesheet,
|
|
12392
12812
|
maskAllInputs: maskInputOptions,
|
|
12393
12813
|
maskTextFn,
|
|
@@ -12436,6 +12856,12 @@ function record(options = {}) {
|
|
|
12436
12856
|
mirror.getId(document)
|
|
12437
12857
|
);
|
|
12438
12858
|
};
|
|
12859
|
+
flushCustomEventQueue = () => {
|
|
12860
|
+
for (const e2 of customEventQueue) {
|
|
12861
|
+
wrappedEmit(e2);
|
|
12862
|
+
}
|
|
12863
|
+
customEventQueue.length = 0;
|
|
12864
|
+
};
|
|
12439
12865
|
try {
|
|
12440
12866
|
const handlers = [];
|
|
12441
12867
|
const observe = (doc) => {
|
|
@@ -12494,6 +12920,7 @@ function record(options = {}) {
|
|
|
12494
12920
|
}
|
|
12495
12921
|
}),
|
|
12496
12922
|
canvasMutationCb: wrappedCanvasMutationEmit,
|
|
12923
|
+
visibilityMutationCb: wrappedVisibilityMutationEmit,
|
|
12497
12924
|
fontCb: (p) => wrappedEmit({
|
|
12498
12925
|
type: EventType.IncrementalSnapshot,
|
|
12499
12926
|
data: {
|
|
@@ -12525,7 +12952,6 @@ function record(options = {}) {
|
|
|
12525
12952
|
maskTextClass,
|
|
12526
12953
|
maskTextSelector,
|
|
12527
12954
|
excludeAttribute,
|
|
12528
|
-
includeAttribute,
|
|
12529
12955
|
maskInputOptions,
|
|
12530
12956
|
inlineStylesheet,
|
|
12531
12957
|
sampling,
|
|
@@ -12547,6 +12973,7 @@ function record(options = {}) {
|
|
|
12547
12973
|
shadowDomManager,
|
|
12548
12974
|
processedNodeManager,
|
|
12549
12975
|
canvasManager,
|
|
12976
|
+
visibilityManager,
|
|
12550
12977
|
ignoreCSSAttributes,
|
|
12551
12978
|
plugins: ((_a2 = plugins == null ? void 0 : plugins.filter((p) => p.observer)) == null ? void 0 : _a2.map((p) => ({
|
|
12552
12979
|
observer: p.observer,
|
|
@@ -12571,14 +12998,14 @@ function record(options = {}) {
|
|
|
12571
12998
|
}
|
|
12572
12999
|
});
|
|
12573
13000
|
const init = () => {
|
|
12574
|
-
if (
|
|
12575
|
-
|
|
13001
|
+
if (flushCustomEvent === "before") {
|
|
13002
|
+
flushCustomEventQueue();
|
|
12576
13003
|
}
|
|
12577
13004
|
takeFullSnapshot$1();
|
|
12578
13005
|
handlers.push(observe(document));
|
|
12579
13006
|
recording = true;
|
|
12580
|
-
if (
|
|
12581
|
-
|
|
13007
|
+
if (flushCustomEvent === "after") {
|
|
13008
|
+
flushCustomEventQueue();
|
|
12582
13009
|
}
|
|
12583
13010
|
};
|
|
12584
13011
|
if (document.readyState === "interactive" || document.readyState === "complete") {
|
|
@@ -12608,7 +13035,7 @@ function record(options = {}) {
|
|
|
12608
13035
|
);
|
|
12609
13036
|
}
|
|
12610
13037
|
return () => {
|
|
12611
|
-
|
|
13038
|
+
flushCustomEventQueue();
|
|
12612
13039
|
handlers.forEach((h) => h());
|
|
12613
13040
|
processedNodeManager.destroy();
|
|
12614
13041
|
recording = false;
|
|
@@ -12618,12 +13045,10 @@ function record(options = {}) {
|
|
|
12618
13045
|
console.warn(error);
|
|
12619
13046
|
}
|
|
12620
13047
|
}
|
|
12621
|
-
|
|
12622
|
-
|
|
12623
|
-
|
|
12624
|
-
|
|
12625
|
-
preRecordingCustomEvents.length = 0;
|
|
12626
|
-
}
|
|
13048
|
+
record.flushCustomEventQueue = () => {
|
|
13049
|
+
console.warn(`[rrweb] CustomEvent flushing: ${customEventQueue.length} events`);
|
|
13050
|
+
flushCustomEventQueue();
|
|
13051
|
+
};
|
|
12627
13052
|
record.addCustomEvent = (tag, payload) => {
|
|
12628
13053
|
const customEvent = {
|
|
12629
13054
|
type: EventType.Custom,
|
|
@@ -12633,8 +13058,8 @@ record.addCustomEvent = (tag, payload) => {
|
|
|
12633
13058
|
}
|
|
12634
13059
|
};
|
|
12635
13060
|
if (!recording) {
|
|
12636
|
-
console.warn(`[rrweb] CustomEvent buffered before recording start: ${tag}`);
|
|
12637
|
-
|
|
13061
|
+
console.warn(`[rrweb] CustomEvent buffered before/after recording start: ${tag}`);
|
|
13062
|
+
customEventQueue.push(customEvent);
|
|
12638
13063
|
return;
|
|
12639
13064
|
}
|
|
12640
13065
|
wrappedEmit(customEvent);
|