@appsurify-testmap/rrweb-all 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-all.cjs +573 -148
- package/dist/rrweb-all.cjs.map +1 -1
- package/dist/rrweb-all.js +573 -148
- package/dist/rrweb-all.js.map +1 -1
- package/dist/rrweb-all.umd.cjs +576 -150
- package/dist/rrweb-all.umd.cjs.map +3 -3
- package/dist/rrweb-all.umd.min.cjs +32 -32
- package/dist/rrweb-all.umd.min.cjs.map +3 -3
- package/package.json +4 -4
package/dist/rrweb-all.js
CHANGED
|
@@ -168,6 +168,41 @@ function patch$1(source, name, replacement) {
|
|
|
168
168
|
};
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
|
+
function describeNode$1(el) {
|
|
172
|
+
const tag = el.tagName.toLowerCase();
|
|
173
|
+
const id = el.id ? `#${el.id}` : "";
|
|
174
|
+
const classes = el.classList.length ? "." + Array.from(el.classList).join(".") : "";
|
|
175
|
+
return `${tag}${id}${classes}`;
|
|
176
|
+
}
|
|
177
|
+
function getElementVisibility$1(el) {
|
|
178
|
+
var _a2, _b2;
|
|
179
|
+
const win = ((_a2 = el.ownerDocument) == null ? void 0 : _a2.defaultView) ?? window;
|
|
180
|
+
const rect = el.getBoundingClientRect();
|
|
181
|
+
const viewportWidth = win.innerWidth || win.document.documentElement.clientWidth || 0;
|
|
182
|
+
const viewportHeight = win.innerHeight || win.document.documentElement.clientHeight || 0;
|
|
183
|
+
const isRectVisible = rect.width > 0 && rect.height > 0 && rect.bottom > 0 && rect.right > 0 && rect.top < viewportHeight && rect.left < viewportWidth;
|
|
184
|
+
const style = (_b2 = win.getComputedStyle) == null ? void 0 : _b2.call(win, el);
|
|
185
|
+
const isStyleVisible2 = !!style && style.display !== "none" && style.visibility !== "hidden" && (parseFloat(style.opacity) || 0) > 0;
|
|
186
|
+
const isVisible = isStyleVisible2 && isRectVisible;
|
|
187
|
+
let ratio = 0;
|
|
188
|
+
if (isVisible) {
|
|
189
|
+
const xOverlap = Math.max(
|
|
190
|
+
0,
|
|
191
|
+
Math.min(rect.right, viewportWidth) - Math.max(rect.left, 0)
|
|
192
|
+
);
|
|
193
|
+
const yOverlap = Math.max(
|
|
194
|
+
0,
|
|
195
|
+
Math.min(rect.bottom, viewportHeight) - Math.max(rect.top, 0)
|
|
196
|
+
);
|
|
197
|
+
const intersectionArea = xOverlap * yOverlap;
|
|
198
|
+
const elementArea = rect.width * rect.height;
|
|
199
|
+
ratio = elementArea > 0 ? intersectionArea / elementArea : 0;
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
isVisible,
|
|
203
|
+
ratio
|
|
204
|
+
};
|
|
205
|
+
}
|
|
171
206
|
const index$1 = {
|
|
172
207
|
childNodes: childNodes$1,
|
|
173
208
|
parentNode: parentNode$1,
|
|
@@ -181,7 +216,9 @@ const index$1 = {
|
|
|
181
216
|
querySelector: querySelector$1,
|
|
182
217
|
querySelectorAll: querySelectorAll$1,
|
|
183
218
|
mutationObserver: mutationObserverCtor$1,
|
|
184
|
-
patch: patch$1
|
|
219
|
+
patch: patch$1,
|
|
220
|
+
describeNode: describeNode$1,
|
|
221
|
+
getElementVisibility: getElementVisibility$1
|
|
185
222
|
};
|
|
186
223
|
function isElement(n2) {
|
|
187
224
|
return n2.nodeType === n2.ELEMENT_NODE;
|
|
@@ -567,71 +604,95 @@ function splitCssText(cssText, style, _testNoPxNorm = false) {
|
|
|
567
604
|
function markCssSplits(cssText, style) {
|
|
568
605
|
return splitCssText(cssText, style).join("/* rr_split */");
|
|
569
606
|
}
|
|
570
|
-
function
|
|
571
|
-
|
|
572
|
-
|
|
607
|
+
function isSelectorUnique(selector, target) {
|
|
608
|
+
try {
|
|
609
|
+
const matches = document.querySelectorAll(selector);
|
|
610
|
+
return matches.length === 1 && matches[0] === target;
|
|
611
|
+
} catch {
|
|
612
|
+
return false;
|
|
573
613
|
}
|
|
574
|
-
|
|
575
|
-
|
|
614
|
+
}
|
|
615
|
+
function buildSelector(node2) {
|
|
616
|
+
if (!(node2 instanceof Element)) return null;
|
|
617
|
+
if (node2.id) {
|
|
618
|
+
return `#${CSS.escape(node2.id)}`;
|
|
576
619
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
}
|
|
582
|
-
if (element.tagName && element.tagName.toLowerCase() === "html") {
|
|
583
|
-
return "/html";
|
|
584
|
-
}
|
|
585
|
-
if (element === document.head) {
|
|
586
|
-
return "/html/head";
|
|
587
|
-
}
|
|
588
|
-
if (element === document.body) {
|
|
589
|
-
return "/html/body";
|
|
590
|
-
}
|
|
591
|
-
const parentNode2 = element.parentNode;
|
|
592
|
-
if (!parentNode2) {
|
|
593
|
-
return "";
|
|
594
|
-
}
|
|
595
|
-
const siblings = Array.from(parentNode2.children).filter(
|
|
596
|
-
(sibling) => sibling.tagName === element.tagName
|
|
597
|
-
);
|
|
598
|
-
const index2 = siblings.length > 1 ? `[${siblings.indexOf(element) + 1}]` : "";
|
|
599
|
-
return `${getXPath(parentNode2)}/${element.tagName.toLowerCase()}${index2}`;
|
|
620
|
+
const parts = [];
|
|
621
|
+
const tag = node2.tagName.toLowerCase();
|
|
622
|
+
if (node2.classList.length) {
|
|
623
|
+
parts.push(...Array.from(node2.classList).map((cls) => `.${CSS.escape(cls)}`));
|
|
600
624
|
}
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
return "";
|
|
625
|
+
Array.from(node2.attributes).forEach((attr) => {
|
|
626
|
+
if (attr.name.startsWith("data-")) {
|
|
627
|
+
parts.push(`[${attr.name}="${CSS.escape(attr.value)}"]`);
|
|
605
628
|
}
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
629
|
+
});
|
|
630
|
+
const shortSelector = `${tag}${parts.join("")}`;
|
|
631
|
+
if (isSelectorUnique(shortSelector, node2)) {
|
|
632
|
+
return shortSelector;
|
|
633
|
+
}
|
|
634
|
+
const pathParts = [];
|
|
635
|
+
let current = node2;
|
|
636
|
+
while (current && current.nodeType === Node.ELEMENT_NODE) {
|
|
637
|
+
const parent = current.parentElement;
|
|
638
|
+
const tagName = current.tagName.toLowerCase();
|
|
639
|
+
let nth = "";
|
|
640
|
+
if (parent) {
|
|
641
|
+
const siblings = Array.from(parent.children).filter(
|
|
642
|
+
(el) => el.tagName.toLowerCase() === tagName
|
|
643
|
+
);
|
|
644
|
+
if (siblings.length > 1) {
|
|
645
|
+
nth = `:nth-of-type(${siblings.indexOf(current) + 1})`;
|
|
646
|
+
}
|
|
616
647
|
}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
);
|
|
620
|
-
const index2 = cdataSiblings.length > 1 ? `[${cdataSiblings.indexOf(node2) + 1}]` : "";
|
|
621
|
-
return `${getXPath(parent)}/text()${index2}`;
|
|
648
|
+
pathParts.unshift(`${tagName}${nth}`);
|
|
649
|
+
current = parent;
|
|
622
650
|
}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
651
|
+
return pathParts.join(" > ") || null;
|
|
652
|
+
}
|
|
653
|
+
function buildXPath(node2) {
|
|
654
|
+
switch (node2.nodeType) {
|
|
655
|
+
case Node.DOCUMENT_NODE:
|
|
656
|
+
return "/";
|
|
657
|
+
case Node.DOCUMENT_TYPE_NODE:
|
|
658
|
+
return "/html/doctype";
|
|
659
|
+
case Node.ELEMENT_NODE: {
|
|
660
|
+
const element = node2;
|
|
661
|
+
if (element.id) {
|
|
662
|
+
return `//*[@id="${CSS.escape(element.id)}"]`;
|
|
663
|
+
}
|
|
664
|
+
if (element.tagName.toLowerCase() === "html") return "/html";
|
|
665
|
+
if (element === document.head) return "/html/head";
|
|
666
|
+
if (element === document.body) return "/html/body";
|
|
667
|
+
const parent = element.parentNode;
|
|
668
|
+
if (!parent) return "";
|
|
669
|
+
const tag = element.tagName.toLowerCase();
|
|
670
|
+
const siblings = Array.from(parent.children).filter(
|
|
671
|
+
(el) => el.tagName.toLowerCase() === tag
|
|
672
|
+
);
|
|
673
|
+
const index2 = siblings.length > 1 ? `[${siblings.indexOf(element) + 1}]` : "";
|
|
674
|
+
return `${buildXPath(parent)}/${tag}${index2}`;
|
|
675
|
+
}
|
|
676
|
+
case Node.TEXT_NODE:
|
|
677
|
+
case Node.CDATA_SECTION_NODE:
|
|
678
|
+
case Node.COMMENT_NODE: {
|
|
679
|
+
const parent = node2.parentNode;
|
|
680
|
+
if (!parent) return "";
|
|
681
|
+
const typeMap = {
|
|
682
|
+
[Node.TEXT_NODE]: "text()",
|
|
683
|
+
[Node.CDATA_SECTION_NODE]: "text()",
|
|
684
|
+
// CDATA ≡ text() в XPath
|
|
685
|
+
[Node.COMMENT_NODE]: "comment()"
|
|
686
|
+
};
|
|
687
|
+
const sameTypeSiblings = Array.from(parent.childNodes).filter(
|
|
688
|
+
(sibling) => sibling.nodeType === node2.nodeType
|
|
689
|
+
);
|
|
690
|
+
const index2 = sameTypeSiblings.length > 1 ? `[${sameTypeSiblings.indexOf(node2)}]` : "";
|
|
691
|
+
return `${buildXPath(parent)}/${typeMap[node2.nodeType]}${index2}`;
|
|
627
692
|
}
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
);
|
|
631
|
-
const index2 = commentSiblings.length > 1 ? `[${commentSiblings.indexOf(node2) + 1}]` : "";
|
|
632
|
-
return `${getXPath(parent)}/comment()${index2}`;
|
|
693
|
+
default:
|
|
694
|
+
return "";
|
|
633
695
|
}
|
|
634
|
-
return "";
|
|
635
696
|
}
|
|
636
697
|
function isTextVisible(n2) {
|
|
637
698
|
var _a2;
|
|
@@ -647,20 +708,9 @@ function isTextVisible(n2) {
|
|
|
647
708
|
const textContent2 = (_a2 = n2.textContent) == null ? void 0 : _a2.trim();
|
|
648
709
|
return textContent2 !== "";
|
|
649
710
|
}
|
|
650
|
-
function isElementVisible(
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
const style = win ? win.getComputedStyle(n2) : null;
|
|
654
|
-
const isStyleVisible = style != null && style.display !== "none" && style.visibility !== "hidden" && parseFloat(style.opacity) !== 0;
|
|
655
|
-
const rect = n2.getBoundingClientRect();
|
|
656
|
-
const result2 = isStyleVisible && isRectVisible(rect);
|
|
657
|
-
return result2;
|
|
658
|
-
}
|
|
659
|
-
function isRectVisible(rect, win = window) {
|
|
660
|
-
var _a2, _b2, _c, _d;
|
|
661
|
-
const height = (win == null ? void 0 : win.innerHeight) ?? ((_b2 = (_a2 = win == null ? void 0 : win.document) == null ? void 0 : _a2.documentElement) == null ? void 0 : _b2.clientHeight) ?? 0;
|
|
662
|
-
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;
|
|
663
|
-
return rect.width > 0 && rect.height > 0 && rect.top >= 0 && rect.left >= 0 && rect.bottom <= height && rect.right <= width;
|
|
711
|
+
function isElementVisible(el) {
|
|
712
|
+
const visibility = index$1.getElementVisibility(el);
|
|
713
|
+
return visibility.isVisible;
|
|
664
714
|
}
|
|
665
715
|
const interactiveEvents$1 = [
|
|
666
716
|
"change",
|
|
@@ -893,9 +943,6 @@ function transformAttribute(doc, tagName, name, value) {
|
|
|
893
943
|
function ignoreAttribute(tagName, name, _value) {
|
|
894
944
|
return (tagName === "video" || tagName === "audio") && name === "autoplay";
|
|
895
945
|
}
|
|
896
|
-
function isIncludeAttribute(name, include) {
|
|
897
|
-
return typeof include === "string" ? name.includes(include) : include.test(name);
|
|
898
|
-
}
|
|
899
946
|
function isExcludeAttribute(name, exclude) {
|
|
900
947
|
return typeof exclude === "string" ? name.includes(exclude) : exclude.test(name);
|
|
901
948
|
}
|
|
@@ -1029,7 +1076,6 @@ function serializeNode(n2, options) {
|
|
|
1029
1076
|
blockClass,
|
|
1030
1077
|
blockSelector,
|
|
1031
1078
|
excludeAttribute,
|
|
1032
|
-
includeAttribute,
|
|
1033
1079
|
needsMask,
|
|
1034
1080
|
inlineStylesheet,
|
|
1035
1081
|
maskInputOptions = {},
|
|
@@ -1043,22 +1089,19 @@ function serializeNode(n2, options) {
|
|
|
1043
1089
|
cssCaptured = false
|
|
1044
1090
|
} = options;
|
|
1045
1091
|
const rootId = getRootId(doc, mirror2);
|
|
1046
|
-
const xPath = getXPath(n2);
|
|
1047
1092
|
switch (n2.nodeType) {
|
|
1048
1093
|
case n2.DOCUMENT_NODE:
|
|
1049
1094
|
if (n2.compatMode !== "CSS1Compat") {
|
|
1050
1095
|
return {
|
|
1051
1096
|
type: NodeType$3.Document,
|
|
1052
1097
|
childNodes: [],
|
|
1053
|
-
xPath,
|
|
1054
1098
|
compatMode: n2.compatMode
|
|
1055
1099
|
// probably "BackCompat"
|
|
1056
1100
|
};
|
|
1057
1101
|
} else {
|
|
1058
1102
|
return {
|
|
1059
1103
|
type: NodeType$3.Document,
|
|
1060
|
-
childNodes: []
|
|
1061
|
-
xPath
|
|
1104
|
+
childNodes: []
|
|
1062
1105
|
};
|
|
1063
1106
|
}
|
|
1064
1107
|
case n2.DOCUMENT_TYPE_NODE:
|
|
@@ -1067,8 +1110,7 @@ function serializeNode(n2, options) {
|
|
|
1067
1110
|
name: n2.name,
|
|
1068
1111
|
publicId: n2.publicId,
|
|
1069
1112
|
systemId: n2.systemId,
|
|
1070
|
-
rootId
|
|
1071
|
-
xPath
|
|
1113
|
+
rootId
|
|
1072
1114
|
};
|
|
1073
1115
|
case n2.ELEMENT_NODE:
|
|
1074
1116
|
return serializeElementNode(n2, {
|
|
@@ -1076,7 +1118,6 @@ function serializeNode(n2, options) {
|
|
|
1076
1118
|
blockClass,
|
|
1077
1119
|
blockSelector,
|
|
1078
1120
|
excludeAttribute,
|
|
1079
|
-
includeAttribute,
|
|
1080
1121
|
inlineStylesheet,
|
|
1081
1122
|
maskInputOptions,
|
|
1082
1123
|
maskInputFn,
|
|
@@ -1085,8 +1126,7 @@ function serializeNode(n2, options) {
|
|
|
1085
1126
|
recordCanvas,
|
|
1086
1127
|
keepIframeSrcFn,
|
|
1087
1128
|
newlyAddedElement,
|
|
1088
|
-
rootId
|
|
1089
|
-
xPath
|
|
1129
|
+
rootId
|
|
1090
1130
|
});
|
|
1091
1131
|
case n2.TEXT_NODE:
|
|
1092
1132
|
return serializeTextNode(n2, {
|
|
@@ -1094,22 +1134,19 @@ function serializeNode(n2, options) {
|
|
|
1094
1134
|
needsMask,
|
|
1095
1135
|
maskTextFn,
|
|
1096
1136
|
rootId,
|
|
1097
|
-
cssCaptured
|
|
1098
|
-
xPath
|
|
1137
|
+
cssCaptured
|
|
1099
1138
|
});
|
|
1100
1139
|
case n2.CDATA_SECTION_NODE:
|
|
1101
1140
|
return {
|
|
1102
1141
|
type: NodeType$3.CDATA,
|
|
1103
1142
|
textContent: "",
|
|
1104
|
-
rootId
|
|
1105
|
-
xPath
|
|
1143
|
+
rootId
|
|
1106
1144
|
};
|
|
1107
1145
|
case n2.COMMENT_NODE:
|
|
1108
1146
|
return {
|
|
1109
1147
|
type: NodeType$3.Comment,
|
|
1110
1148
|
textContent: index$1.textContent(n2) || "",
|
|
1111
|
-
rootId
|
|
1112
|
-
xPath
|
|
1149
|
+
rootId
|
|
1113
1150
|
};
|
|
1114
1151
|
default:
|
|
1115
1152
|
return false;
|
|
@@ -1121,7 +1158,7 @@ function getRootId(doc, mirror2) {
|
|
|
1121
1158
|
return docId === 1 ? void 0 : docId;
|
|
1122
1159
|
}
|
|
1123
1160
|
function serializeTextNode(n2, options) {
|
|
1124
|
-
const { needsMask, maskTextFn, rootId, cssCaptured
|
|
1161
|
+
const { needsMask, maskTextFn, rootId, cssCaptured } = options;
|
|
1125
1162
|
const parent = index$1.parentNode(n2);
|
|
1126
1163
|
const parentTagName = parent && parent.tagName;
|
|
1127
1164
|
let textContent2 = "";
|
|
@@ -1138,15 +1175,10 @@ function serializeTextNode(n2, options) {
|
|
|
1138
1175
|
if (!isStyle && !isScript && textContent2 && needsMask) {
|
|
1139
1176
|
textContent2 = maskTextFn ? maskTextFn(textContent2, index$1.parentElement(n2)) : textContent2.replace(/[\S]/g, "*");
|
|
1140
1177
|
}
|
|
1141
|
-
const isVisible = isTextVisible(n2);
|
|
1142
|
-
const isInteractive = isElementInteractive(n2);
|
|
1143
1178
|
return {
|
|
1144
1179
|
type: NodeType$3.Text,
|
|
1145
1180
|
textContent: textContent2 || "",
|
|
1146
|
-
rootId
|
|
1147
|
-
isVisible,
|
|
1148
|
-
isInteractive,
|
|
1149
|
-
xPath
|
|
1181
|
+
rootId
|
|
1150
1182
|
};
|
|
1151
1183
|
}
|
|
1152
1184
|
function serializeElementNode(n2, options) {
|
|
@@ -1155,7 +1187,6 @@ function serializeElementNode(n2, options) {
|
|
|
1155
1187
|
blockClass,
|
|
1156
1188
|
blockSelector,
|
|
1157
1189
|
excludeAttribute,
|
|
1158
|
-
includeAttribute,
|
|
1159
1190
|
inlineStylesheet,
|
|
1160
1191
|
maskInputOptions = {},
|
|
1161
1192
|
maskInputFn,
|
|
@@ -1164,8 +1195,7 @@ function serializeElementNode(n2, options) {
|
|
|
1164
1195
|
recordCanvas,
|
|
1165
1196
|
keepIframeSrcFn,
|
|
1166
1197
|
newlyAddedElement = false,
|
|
1167
|
-
rootId
|
|
1168
|
-
xPath
|
|
1198
|
+
rootId
|
|
1169
1199
|
} = options;
|
|
1170
1200
|
const needBlock = _isBlockedElement(n2, blockClass, blockSelector);
|
|
1171
1201
|
const tagName = getValidTagName$1(n2);
|
|
@@ -1173,7 +1203,7 @@ function serializeElementNode(n2, options) {
|
|
|
1173
1203
|
const len = n2.attributes.length;
|
|
1174
1204
|
for (let i2 = 0; i2 < len; i2++) {
|
|
1175
1205
|
const attr = n2.attributes[i2];
|
|
1176
|
-
if (isExcludeAttribute(attr.name, excludeAttribute)
|
|
1206
|
+
if (isExcludeAttribute(attr.name, excludeAttribute)) {
|
|
1177
1207
|
continue;
|
|
1178
1208
|
}
|
|
1179
1209
|
if (!ignoreAttribute(tagName, attr.name, attr.value)) {
|
|
@@ -1335,8 +1365,6 @@ function serializeElementNode(n2, options) {
|
|
|
1335
1365
|
if (customElements.get(tagName)) isCustomElement = true;
|
|
1336
1366
|
} catch (e2) {
|
|
1337
1367
|
}
|
|
1338
|
-
const isVisible = isElementVisible(n2);
|
|
1339
|
-
const isInteractive = isElementInteractive(n2);
|
|
1340
1368
|
return {
|
|
1341
1369
|
type: NodeType$3.Element,
|
|
1342
1370
|
tagName,
|
|
@@ -1345,10 +1373,7 @@ function serializeElementNode(n2, options) {
|
|
|
1345
1373
|
isSVG: isSVGElement(n2) || void 0,
|
|
1346
1374
|
needBlock,
|
|
1347
1375
|
rootId,
|
|
1348
|
-
isCustom: isCustomElement
|
|
1349
|
-
isVisible,
|
|
1350
|
-
isInteractive,
|
|
1351
|
-
xPath
|
|
1376
|
+
isCustom: isCustomElement
|
|
1352
1377
|
};
|
|
1353
1378
|
}
|
|
1354
1379
|
function lowerIfExists(maybeAttr) {
|
|
@@ -1399,7 +1424,6 @@ function serializeNodeWithId(n2, options) {
|
|
|
1399
1424
|
maskTextClass,
|
|
1400
1425
|
maskTextSelector,
|
|
1401
1426
|
excludeAttribute,
|
|
1402
|
-
includeAttribute,
|
|
1403
1427
|
skipChild = false,
|
|
1404
1428
|
inlineStylesheet = true,
|
|
1405
1429
|
maskInputOptions = {},
|
|
@@ -1435,7 +1459,6 @@ function serializeNodeWithId(n2, options) {
|
|
|
1435
1459
|
blockClass,
|
|
1436
1460
|
blockSelector,
|
|
1437
1461
|
excludeAttribute,
|
|
1438
|
-
includeAttribute,
|
|
1439
1462
|
needsMask,
|
|
1440
1463
|
inlineStylesheet,
|
|
1441
1464
|
maskInputOptions,
|
|
@@ -1461,6 +1484,22 @@ function serializeNodeWithId(n2, options) {
|
|
|
1461
1484
|
id = genId();
|
|
1462
1485
|
}
|
|
1463
1486
|
const serializedNode = Object.assign(_serializedNode, { id });
|
|
1487
|
+
if (isElement(n2) || n2.nodeType === Node.TEXT_NODE) {
|
|
1488
|
+
serializedNode.xpath = buildXPath(n2);
|
|
1489
|
+
if (isElement(n2)) {
|
|
1490
|
+
const selector = buildSelector(n2);
|
|
1491
|
+
if (selector) {
|
|
1492
|
+
serializedNode.selector = selector;
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
if (n2.nodeType === Node.TEXT_NODE) {
|
|
1496
|
+
serializedNode.isVisible = isTextVisible(n2);
|
|
1497
|
+
}
|
|
1498
|
+
if (n2.nodeType === Node.ELEMENT_NODE) {
|
|
1499
|
+
serializedNode.isVisible = isElementVisible(n2);
|
|
1500
|
+
serializedNode.isInteractive = isElementInteractive(n2);
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1464
1503
|
mirror2.add(n2, serializedNode);
|
|
1465
1504
|
if (id === IGNORED_NODE) {
|
|
1466
1505
|
return null;
|
|
@@ -1489,7 +1528,6 @@ function serializeNodeWithId(n2, options) {
|
|
|
1489
1528
|
maskTextClass,
|
|
1490
1529
|
maskTextSelector,
|
|
1491
1530
|
excludeAttribute,
|
|
1492
|
-
includeAttribute,
|
|
1493
1531
|
skipChild,
|
|
1494
1532
|
inlineStylesheet,
|
|
1495
1533
|
maskInputOptions,
|
|
@@ -1550,7 +1588,6 @@ function serializeNodeWithId(n2, options) {
|
|
|
1550
1588
|
maskTextClass,
|
|
1551
1589
|
maskTextSelector,
|
|
1552
1590
|
excludeAttribute,
|
|
1553
|
-
includeAttribute,
|
|
1554
1591
|
skipChild: false,
|
|
1555
1592
|
inlineStylesheet,
|
|
1556
1593
|
maskInputOptions,
|
|
@@ -1593,7 +1630,6 @@ function serializeNodeWithId(n2, options) {
|
|
|
1593
1630
|
maskTextClass,
|
|
1594
1631
|
maskTextSelector,
|
|
1595
1632
|
excludeAttribute,
|
|
1596
|
-
includeAttribute,
|
|
1597
1633
|
skipChild: false,
|
|
1598
1634
|
inlineStylesheet,
|
|
1599
1635
|
maskInputOptions,
|
|
@@ -1631,8 +1667,7 @@ function snapshot(n2, options) {
|
|
|
1631
1667
|
blockSelector = null,
|
|
1632
1668
|
maskTextClass = "rr-mask",
|
|
1633
1669
|
maskTextSelector = null,
|
|
1634
|
-
excludeAttribute =
|
|
1635
|
-
includeAttribute = /.+/i,
|
|
1670
|
+
excludeAttribute = /.^/,
|
|
1636
1671
|
inlineStylesheet = true,
|
|
1637
1672
|
inlineImages = false,
|
|
1638
1673
|
recordCanvas = false,
|
|
@@ -1693,7 +1728,6 @@ function snapshot(n2, options) {
|
|
|
1693
1728
|
maskTextClass,
|
|
1694
1729
|
maskTextSelector,
|
|
1695
1730
|
excludeAttribute,
|
|
1696
|
-
includeAttribute,
|
|
1697
1731
|
skipChild: false,
|
|
1698
1732
|
inlineStylesheet,
|
|
1699
1733
|
maskInputOptions,
|
|
@@ -10832,6 +10866,41 @@ function patch(source, name, replacement) {
|
|
|
10832
10866
|
};
|
|
10833
10867
|
}
|
|
10834
10868
|
}
|
|
10869
|
+
function describeNode(el) {
|
|
10870
|
+
const tag = el.tagName.toLowerCase();
|
|
10871
|
+
const id = el.id ? `#${el.id}` : "";
|
|
10872
|
+
const classes = el.classList.length ? "." + Array.from(el.classList).join(".") : "";
|
|
10873
|
+
return `${tag}${id}${classes}`;
|
|
10874
|
+
}
|
|
10875
|
+
function getElementVisibility(el) {
|
|
10876
|
+
var _a2, _b2;
|
|
10877
|
+
const win = ((_a2 = el.ownerDocument) == null ? void 0 : _a2.defaultView) ?? window;
|
|
10878
|
+
const rect = el.getBoundingClientRect();
|
|
10879
|
+
const viewportWidth = win.innerWidth || win.document.documentElement.clientWidth || 0;
|
|
10880
|
+
const viewportHeight = win.innerHeight || win.document.documentElement.clientHeight || 0;
|
|
10881
|
+
const isRectVisible = rect.width > 0 && rect.height > 0 && rect.bottom > 0 && rect.right > 0 && rect.top < viewportHeight && rect.left < viewportWidth;
|
|
10882
|
+
const style = (_b2 = win.getComputedStyle) == null ? void 0 : _b2.call(win, el);
|
|
10883
|
+
const isStyleVisible2 = !!style && style.display !== "none" && style.visibility !== "hidden" && (parseFloat(style.opacity) || 0) > 0;
|
|
10884
|
+
const isVisible = isStyleVisible2 && isRectVisible;
|
|
10885
|
+
let ratio = 0;
|
|
10886
|
+
if (isVisible) {
|
|
10887
|
+
const xOverlap = Math.max(
|
|
10888
|
+
0,
|
|
10889
|
+
Math.min(rect.right, viewportWidth) - Math.max(rect.left, 0)
|
|
10890
|
+
);
|
|
10891
|
+
const yOverlap = Math.max(
|
|
10892
|
+
0,
|
|
10893
|
+
Math.min(rect.bottom, viewportHeight) - Math.max(rect.top, 0)
|
|
10894
|
+
);
|
|
10895
|
+
const intersectionArea = xOverlap * yOverlap;
|
|
10896
|
+
const elementArea = rect.width * rect.height;
|
|
10897
|
+
ratio = elementArea > 0 ? intersectionArea / elementArea : 0;
|
|
10898
|
+
}
|
|
10899
|
+
return {
|
|
10900
|
+
isVisible,
|
|
10901
|
+
ratio
|
|
10902
|
+
};
|
|
10903
|
+
}
|
|
10835
10904
|
const index = {
|
|
10836
10905
|
childNodes,
|
|
10837
10906
|
parentNode,
|
|
@@ -10845,7 +10914,9 @@ const index = {
|
|
|
10845
10914
|
querySelector,
|
|
10846
10915
|
querySelectorAll,
|
|
10847
10916
|
mutationObserver: mutationObserverCtor,
|
|
10848
|
-
patch
|
|
10917
|
+
patch,
|
|
10918
|
+
describeNode,
|
|
10919
|
+
getElementVisibility
|
|
10849
10920
|
};
|
|
10850
10921
|
function on(type, fn, target = document) {
|
|
10851
10922
|
const options = { capture: true, passive: true };
|
|
@@ -11246,6 +11317,7 @@ var IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {
|
|
|
11246
11317
|
IncrementalSource2[IncrementalSource2["Selection"] = 14] = "Selection";
|
|
11247
11318
|
IncrementalSource2[IncrementalSource2["AdoptedStyleSheet"] = 15] = "AdoptedStyleSheet";
|
|
11248
11319
|
IncrementalSource2[IncrementalSource2["CustomElement"] = 16] = "CustomElement";
|
|
11320
|
+
IncrementalSource2[IncrementalSource2["VisibilityMutation"] = 17] = "VisibilityMutation";
|
|
11249
11321
|
return IncrementalSource2;
|
|
11250
11322
|
})(IncrementalSource || {});
|
|
11251
11323
|
var MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {
|
|
@@ -11412,7 +11484,6 @@ class MutationBuffer {
|
|
|
11412
11484
|
__publicField(this, "maskTextClass");
|
|
11413
11485
|
__publicField(this, "maskTextSelector");
|
|
11414
11486
|
__publicField(this, "excludeAttribute");
|
|
11415
|
-
__publicField(this, "includeAttribute");
|
|
11416
11487
|
__publicField(this, "inlineStylesheet");
|
|
11417
11488
|
__publicField(this, "maskInputOptions");
|
|
11418
11489
|
__publicField(this, "maskTextFn");
|
|
@@ -11428,6 +11499,7 @@ class MutationBuffer {
|
|
|
11428
11499
|
__publicField(this, "stylesheetManager");
|
|
11429
11500
|
__publicField(this, "shadowDomManager");
|
|
11430
11501
|
__publicField(this, "canvasManager");
|
|
11502
|
+
__publicField(this, "visibilityManager");
|
|
11431
11503
|
__publicField(this, "processedNodeManager");
|
|
11432
11504
|
__publicField(this, "unattachedDoc");
|
|
11433
11505
|
__publicField(this, "processMutations", (mutations) => {
|
|
@@ -11477,7 +11549,6 @@ class MutationBuffer {
|
|
|
11477
11549
|
maskTextClass: this.maskTextClass,
|
|
11478
11550
|
maskTextSelector: this.maskTextSelector,
|
|
11479
11551
|
excludeAttribute: this.excludeAttribute,
|
|
11480
|
-
includeAttribute: this.includeAttribute,
|
|
11481
11552
|
skipChild: true,
|
|
11482
11553
|
newlyAddedElement: true,
|
|
11483
11554
|
inlineStylesheet: this.inlineStylesheet,
|
|
@@ -11523,7 +11594,8 @@ class MutationBuffer {
|
|
|
11523
11594
|
this.mirror.removeNodeFromMap(this.mapRemoves.shift());
|
|
11524
11595
|
}
|
|
11525
11596
|
for (const n2 of this.movedSet) {
|
|
11526
|
-
if (isParentRemoved(this.removesSubTreeCache, n2, this.mirror) &&
|
|
11597
|
+
if (isParentRemoved(this.removesSubTreeCache, n2, this.mirror) && // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
11598
|
+
!this.movedSet.has(index.parentNode(n2))) {
|
|
11527
11599
|
continue;
|
|
11528
11600
|
}
|
|
11529
11601
|
pushAdd(n2);
|
|
@@ -11679,12 +11751,60 @@ class MutationBuffer {
|
|
|
11679
11751
|
const target = m.target;
|
|
11680
11752
|
let attributeName = m.attributeName;
|
|
11681
11753
|
let value = m.target.getAttribute(attributeName);
|
|
11682
|
-
const
|
|
11683
|
-
const
|
|
11754
|
+
const attrKey = attributeName;
|
|
11755
|
+
const propValue = target[attrKey];
|
|
11756
|
+
const isBooleanAttr = typeof propValue === "boolean";
|
|
11757
|
+
const inDOM = document.contains(target);
|
|
11758
|
+
const isVisible = isElementVisible(target);
|
|
11759
|
+
const isExcludeAttributeName = isExcludeAttribute(attributeName, this.excludeAttribute);
|
|
11760
|
+
const isPhantomAttributeMutation = value === null && // текущего атрибута нет
|
|
11761
|
+
!target.hasAttribute(attributeName) && // явно подтверждаем отсутствие
|
|
11762
|
+
m.oldValue !== null && // раньше он был
|
|
11763
|
+
(propValue === "" || // свойство = пустая строка
|
|
11764
|
+
propValue === null || // или null
|
|
11765
|
+
typeof propValue === "undefined");
|
|
11684
11766
|
if (isPhantomAttributeMutation) {
|
|
11767
|
+
console.debug(
|
|
11768
|
+
`[${nowTimestamp()}] [rrweb:record/mutation] ⛔ phantom attribute mutation ignored`,
|
|
11769
|
+
{
|
|
11770
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
|
11771
|
+
node: index.describeNode(target),
|
|
11772
|
+
tag: target.tagName,
|
|
11773
|
+
nodeType: target.nodeType,
|
|
11774
|
+
attribute: attributeName,
|
|
11775
|
+
value,
|
|
11776
|
+
oldValue: m.oldValue,
|
|
11777
|
+
excludeAttribute: this.excludeAttribute,
|
|
11778
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
11779
|
+
propValue,
|
|
11780
|
+
isBooleanAttr,
|
|
11781
|
+
inDOM,
|
|
11782
|
+
isVisible,
|
|
11783
|
+
isExcludeAttributeName
|
|
11784
|
+
}
|
|
11785
|
+
);
|
|
11685
11786
|
return;
|
|
11686
11787
|
}
|
|
11687
11788
|
if (isExcludeAttribute(attributeName, this.excludeAttribute)) {
|
|
11789
|
+
console.debug(
|
|
11790
|
+
`[${nowTimestamp()}] [rrweb:record/mutation] ⛔ excluded attribute mutation ignored`,
|
|
11791
|
+
{
|
|
11792
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
|
11793
|
+
node: index.describeNode(target),
|
|
11794
|
+
tag: target.tagName,
|
|
11795
|
+
nodeType: target.nodeType,
|
|
11796
|
+
attribute: attributeName,
|
|
11797
|
+
value,
|
|
11798
|
+
oldValue: m.oldValue,
|
|
11799
|
+
excludeAttribute: this.excludeAttribute,
|
|
11800
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
11801
|
+
propValue,
|
|
11802
|
+
isBooleanAttr,
|
|
11803
|
+
inDOM,
|
|
11804
|
+
isVisible,
|
|
11805
|
+
isExcludeAttributeName
|
|
11806
|
+
}
|
|
11807
|
+
);
|
|
11688
11808
|
return;
|
|
11689
11809
|
}
|
|
11690
11810
|
if (attributeName === "value") {
|
|
@@ -11729,9 +11849,35 @@ class MutationBuffer {
|
|
|
11729
11849
|
toLowerCase(attributeName),
|
|
11730
11850
|
value
|
|
11731
11851
|
);
|
|
11732
|
-
|
|
11733
|
-
|
|
11734
|
-
|
|
11852
|
+
const isSuspiciousClassMutation = attributeName !== "class" && (m.oldValue === null || // ранее не было класса
|
|
11853
|
+
value === "" || // класс удалён
|
|
11854
|
+
value !== m.oldValue);
|
|
11855
|
+
if (isSuspiciousClassMutation) {
|
|
11856
|
+
console.debug(
|
|
11857
|
+
`[${nowTimestamp()}] [rrweb:record/mutation] ⚠️ suspicious attribute mutation`,
|
|
11858
|
+
{
|
|
11859
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call
|
|
11860
|
+
reason: [
|
|
11861
|
+
value === m.oldValue ? "no change in value" : null,
|
|
11862
|
+
value === propValue ? "mirrored in DOM property" : null,
|
|
11863
|
+
value === item.attributes[attributeName] ? "redundant assignment" : null
|
|
11864
|
+
].filter(Boolean).join(", ") || "uncategorized",
|
|
11865
|
+
node: index.describeNode(target),
|
|
11866
|
+
tag: target.tagName,
|
|
11867
|
+
nodeType: target.nodeType,
|
|
11868
|
+
attribute: attributeName,
|
|
11869
|
+
value,
|
|
11870
|
+
oldValue: m.oldValue,
|
|
11871
|
+
transformedValue: item.attributes[attributeName],
|
|
11872
|
+
excludeAttribute: this.excludeAttribute,
|
|
11873
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
11874
|
+
propValue,
|
|
11875
|
+
isBooleanAttr,
|
|
11876
|
+
inDOM,
|
|
11877
|
+
isVisible,
|
|
11878
|
+
isExcludeAttributeName
|
|
11879
|
+
}
|
|
11880
|
+
);
|
|
11735
11881
|
}
|
|
11736
11882
|
if (attributeName === "style") {
|
|
11737
11883
|
if (!this.unattachedDoc) {
|
|
@@ -11846,7 +11992,6 @@ class MutationBuffer {
|
|
|
11846
11992
|
"maskTextClass",
|
|
11847
11993
|
"maskTextSelector",
|
|
11848
11994
|
"excludeAttribute",
|
|
11849
|
-
"includeAttribute",
|
|
11850
11995
|
"inlineStylesheet",
|
|
11851
11996
|
"maskInputOptions",
|
|
11852
11997
|
"maskTextFn",
|
|
@@ -11862,6 +12007,7 @@ class MutationBuffer {
|
|
|
11862
12007
|
"stylesheetManager",
|
|
11863
12008
|
"shadowDomManager",
|
|
11864
12009
|
"canvasManager",
|
|
12010
|
+
"visibilityManager",
|
|
11865
12011
|
"processedNodeManager"
|
|
11866
12012
|
].forEach((key) => {
|
|
11867
12013
|
this[key] = options[key];
|
|
@@ -11870,10 +12016,12 @@ class MutationBuffer {
|
|
|
11870
12016
|
freeze() {
|
|
11871
12017
|
this.frozen = true;
|
|
11872
12018
|
this.canvasManager.freeze();
|
|
12019
|
+
this.visibilityManager.freeze();
|
|
11873
12020
|
}
|
|
11874
12021
|
unfreeze() {
|
|
11875
12022
|
this.frozen = false;
|
|
11876
12023
|
this.canvasManager.unfreeze();
|
|
12024
|
+
this.visibilityManager.unfreeze();
|
|
11877
12025
|
this.emit();
|
|
11878
12026
|
}
|
|
11879
12027
|
isFrozen() {
|
|
@@ -11882,15 +12030,18 @@ class MutationBuffer {
|
|
|
11882
12030
|
lock() {
|
|
11883
12031
|
this.locked = true;
|
|
11884
12032
|
this.canvasManager.lock();
|
|
12033
|
+
this.visibilityManager.lock();
|
|
11885
12034
|
}
|
|
11886
12035
|
unlock() {
|
|
11887
12036
|
this.locked = false;
|
|
11888
12037
|
this.canvasManager.unlock();
|
|
12038
|
+
this.visibilityManager.unlock();
|
|
11889
12039
|
this.emit();
|
|
11890
12040
|
}
|
|
11891
12041
|
reset() {
|
|
11892
12042
|
this.shadowDomManager.reset();
|
|
11893
12043
|
this.canvasManager.reset();
|
|
12044
|
+
this.visibilityManager.reset();
|
|
11894
12045
|
}
|
|
11895
12046
|
}
|
|
11896
12047
|
function deepDelete(addsSet, n2) {
|
|
@@ -12824,6 +12975,7 @@ function mergeHooks(o2, hooks) {
|
|
|
12824
12975
|
styleSheetRuleCb,
|
|
12825
12976
|
styleDeclarationCb,
|
|
12826
12977
|
canvasMutationCb,
|
|
12978
|
+
visibilityMutationCb,
|
|
12827
12979
|
fontCb,
|
|
12828
12980
|
selectionCb,
|
|
12829
12981
|
customElementCb
|
|
@@ -12888,6 +13040,12 @@ function mergeHooks(o2, hooks) {
|
|
|
12888
13040
|
}
|
|
12889
13041
|
canvasMutationCb(...p);
|
|
12890
13042
|
};
|
|
13043
|
+
o2.visibilityMutationCb = (...p) => {
|
|
13044
|
+
if (hooks.visibilityMutation) {
|
|
13045
|
+
hooks.visibilityMutation(...p);
|
|
13046
|
+
}
|
|
13047
|
+
visibilityMutationCb(...p);
|
|
13048
|
+
};
|
|
12891
13049
|
o2.fontCb = (...p) => {
|
|
12892
13050
|
if (hooks.font) {
|
|
12893
13051
|
hooks.font(...p);
|
|
@@ -14021,11 +14179,249 @@ class ProcessedNodeManager {
|
|
|
14021
14179
|
destroy() {
|
|
14022
14180
|
}
|
|
14023
14181
|
}
|
|
14182
|
+
function computeVisibility(elements, previous, options) {
|
|
14183
|
+
const root2 = (options == null ? void 0 : options.root) ?? null;
|
|
14184
|
+
const threshold = (options == null ? void 0 : options.threshold) ?? 0.5;
|
|
14185
|
+
const sensitivity = (options == null ? void 0 : options.sensitivity) ?? 0.05;
|
|
14186
|
+
const rootMarginFn = parseRootMargin((options == null ? void 0 : options.rootMargin) ?? "0px");
|
|
14187
|
+
const current = /* @__PURE__ */ new Map();
|
|
14188
|
+
const rootRect = getRootRect(root2);
|
|
14189
|
+
const expandedRoot = expandRootRect(rootRect, rootMarginFn);
|
|
14190
|
+
for (const el of elements) {
|
|
14191
|
+
const elRect = el.getBoundingClientRect();
|
|
14192
|
+
let intersectionRect = emptyRect();
|
|
14193
|
+
let intersectionRatio = 0;
|
|
14194
|
+
if (elRect.width > 0 && elRect.height > 0) {
|
|
14195
|
+
intersectionRect = computeIntersectionRect(elRect, expandedRoot);
|
|
14196
|
+
intersectionRatio = computeIntersectionRatio(elRect, intersectionRect);
|
|
14197
|
+
intersectionRatio = Math.round(intersectionRatio * 100) / 100;
|
|
14198
|
+
}
|
|
14199
|
+
const isStyle = isStyleVisible(el);
|
|
14200
|
+
const old = previous.get(el) ?? null;
|
|
14201
|
+
const prevRatio = (old == null ? void 0 : old.intersectionRatio) ?? 0;
|
|
14202
|
+
const currRatio = intersectionRatio;
|
|
14203
|
+
const wasVisible = (old == null ? void 0 : old.isStyleVisible) && prevRatio > threshold;
|
|
14204
|
+
const nowVisible = isStyle && currRatio > threshold;
|
|
14205
|
+
const changed = !old || wasVisible !== nowVisible || wasVisible !== nowVisible && Math.abs(currRatio - prevRatio) > sensitivity;
|
|
14206
|
+
if (changed) {
|
|
14207
|
+
current.set(el, {
|
|
14208
|
+
target: el,
|
|
14209
|
+
isVisible: nowVisible,
|
|
14210
|
+
isStyleVisible: isStyle,
|
|
14211
|
+
intersectionRatio: currRatio,
|
|
14212
|
+
intersectionRect,
|
|
14213
|
+
oldValue: old
|
|
14214
|
+
});
|
|
14215
|
+
} else {
|
|
14216
|
+
current.set(el, old);
|
|
14217
|
+
}
|
|
14218
|
+
}
|
|
14219
|
+
return current;
|
|
14220
|
+
}
|
|
14221
|
+
function parseRootMargin(marginStr) {
|
|
14222
|
+
const parts = marginStr.trim().split(/\s+/);
|
|
14223
|
+
const getValue = (val, size) => val.endsWith("%") ? parseFloat(val) / 100 * size : parseFloat(val) || 0;
|
|
14224
|
+
return function(rootRect) {
|
|
14225
|
+
const top = getValue(parts[0] || "0px", rootRect.height);
|
|
14226
|
+
const right = getValue(parts[1] || parts[0] || "0px", rootRect.width);
|
|
14227
|
+
const bottom = getValue(parts[2] || parts[0] || "0px", rootRect.height);
|
|
14228
|
+
const left = getValue(parts[3] || parts[1] || parts[0] || "0px", rootRect.width);
|
|
14229
|
+
return { top, right, bottom, left, width: 0, height: 0 };
|
|
14230
|
+
};
|
|
14231
|
+
}
|
|
14232
|
+
function getRootRect(root2) {
|
|
14233
|
+
return root2 ? root2.getBoundingClientRect() : new DOMRect(0, 0, window.innerWidth, window.innerHeight);
|
|
14234
|
+
}
|
|
14235
|
+
function expandRootRect(rect, marginFn) {
|
|
14236
|
+
const margin = marginFn(rect);
|
|
14237
|
+
return new DOMRect(
|
|
14238
|
+
rect.left - margin.left,
|
|
14239
|
+
rect.top - margin.top,
|
|
14240
|
+
rect.width + margin.left + margin.right,
|
|
14241
|
+
rect.height + margin.top + margin.bottom
|
|
14242
|
+
);
|
|
14243
|
+
}
|
|
14244
|
+
function computeIntersectionRect(a2, b) {
|
|
14245
|
+
const top = Math.max(a2.top, b.top);
|
|
14246
|
+
const left = Math.max(a2.left, b.left);
|
|
14247
|
+
const bottom = Math.min(a2.bottom, b.bottom);
|
|
14248
|
+
const right = Math.min(a2.right, b.right);
|
|
14249
|
+
const width = Math.max(0, right - left);
|
|
14250
|
+
const height = Math.max(0, bottom - top);
|
|
14251
|
+
return { top, left, bottom, right, width, height };
|
|
14252
|
+
}
|
|
14253
|
+
function computeIntersectionRatio(elRect, intersectionRect) {
|
|
14254
|
+
const elArea = elRect.width * elRect.height;
|
|
14255
|
+
const intArea = intersectionRect.width * intersectionRect.height;
|
|
14256
|
+
return elArea > 0 ? intArea / elArea : 0;
|
|
14257
|
+
}
|
|
14258
|
+
function emptyRect() {
|
|
14259
|
+
return { top: 0, left: 0, right: 0, bottom: 0, width: 0, height: 0 };
|
|
14260
|
+
}
|
|
14261
|
+
function isStyleVisible(el) {
|
|
14262
|
+
const style = getComputedStyle(el);
|
|
14263
|
+
return style && style.display !== "none" && style.visibility !== "hidden" && parseFloat(style.opacity || "1") > 0;
|
|
14264
|
+
}
|
|
14265
|
+
class VisibilityManager {
|
|
14266
|
+
constructor(options) {
|
|
14267
|
+
__publicField(this, "frozen", false);
|
|
14268
|
+
__publicField(this, "locked", false);
|
|
14269
|
+
__publicField(this, "pending", /* @__PURE__ */ new Map());
|
|
14270
|
+
__publicField(this, "mirror");
|
|
14271
|
+
__publicField(this, "mutationCb");
|
|
14272
|
+
__publicField(this, "rafId", null);
|
|
14273
|
+
__publicField(this, "rafThrottle");
|
|
14274
|
+
__publicField(this, "lastFlushTime", 0);
|
|
14275
|
+
__publicField(this, "elements", /* @__PURE__ */ new Set());
|
|
14276
|
+
__publicField(this, "previousState", /* @__PURE__ */ new Map());
|
|
14277
|
+
__publicField(this, "root", null);
|
|
14278
|
+
__publicField(this, "threshold");
|
|
14279
|
+
__publicField(this, "sensitivity");
|
|
14280
|
+
__publicField(this, "rootMargin");
|
|
14281
|
+
__publicField(this, "hasInitialized", false);
|
|
14282
|
+
__publicField(this, "mode", "none");
|
|
14283
|
+
__publicField(this, "debounce", 50);
|
|
14284
|
+
__publicField(this, "throttle", 100);
|
|
14285
|
+
__publicField(this, "buffer", /* @__PURE__ */ new Map());
|
|
14286
|
+
__publicField(this, "debounceTimer", null);
|
|
14287
|
+
__publicField(this, "lastThrottleTime", 0);
|
|
14288
|
+
__publicField(this, "disabled", false);
|
|
14289
|
+
__publicField(this, "notifyActivity");
|
|
14290
|
+
const { doc, mirror: mirror2, sampling, mutationCb, notifyActivity } = options;
|
|
14291
|
+
this.mirror = mirror2;
|
|
14292
|
+
this.mutationCb = mutationCb;
|
|
14293
|
+
this.notifyActivity = notifyActivity;
|
|
14294
|
+
this.rootMargin = "0px";
|
|
14295
|
+
if (sampling === false) {
|
|
14296
|
+
this.disabled = true;
|
|
14297
|
+
return;
|
|
14298
|
+
}
|
|
14299
|
+
const visibilitySampling = typeof sampling === "object" && sampling !== null ? sampling : {};
|
|
14300
|
+
this.mode = (visibilitySampling == null ? void 0 : visibilitySampling.mode) ?? "none";
|
|
14301
|
+
this.debounce = Number((visibilitySampling == null ? void 0 : visibilitySampling.debounce) ?? 100);
|
|
14302
|
+
this.throttle = Number((visibilitySampling == null ? void 0 : visibilitySampling.throttle) ?? 100);
|
|
14303
|
+
this.threshold = Number((visibilitySampling == null ? void 0 : visibilitySampling.threshold) ?? 0.5);
|
|
14304
|
+
this.sensitivity = Number((visibilitySampling == null ? void 0 : visibilitySampling.sensitivity) ?? 0.05);
|
|
14305
|
+
this.rafThrottle = Number((visibilitySampling == null ? void 0 : visibilitySampling.rafThrottle) ?? 100);
|
|
14306
|
+
doc.querySelectorAll("*").forEach((el) => this.observe(el));
|
|
14307
|
+
const mo = new MutationObserver((mutations) => {
|
|
14308
|
+
mutations.forEach((m) => {
|
|
14309
|
+
m.addedNodes.forEach((n2) => {
|
|
14310
|
+
if (n2.nodeType === Node.ELEMENT_NODE) {
|
|
14311
|
+
this.observe(n2);
|
|
14312
|
+
n2.querySelectorAll("*").forEach((el) => this.observe(el));
|
|
14313
|
+
}
|
|
14314
|
+
});
|
|
14315
|
+
m.removedNodes.forEach((n2) => {
|
|
14316
|
+
if (n2.nodeType === Node.ELEMENT_NODE) {
|
|
14317
|
+
this.unobserve(n2);
|
|
14318
|
+
}
|
|
14319
|
+
});
|
|
14320
|
+
});
|
|
14321
|
+
});
|
|
14322
|
+
mo.observe(doc.body, { childList: true, subtree: true });
|
|
14323
|
+
this.startPendingFlushLoop();
|
|
14324
|
+
}
|
|
14325
|
+
startPendingFlushLoop() {
|
|
14326
|
+
if (this.disabled) return;
|
|
14327
|
+
const loop = (timestamp) => {
|
|
14328
|
+
if (timestamp - this.lastFlushTime >= this.rafThrottle) {
|
|
14329
|
+
this.lastFlushTime = timestamp;
|
|
14330
|
+
this.flushPendingVisibilityMutations();
|
|
14331
|
+
}
|
|
14332
|
+
this.rafId = requestAnimationFrame(loop);
|
|
14333
|
+
};
|
|
14334
|
+
this.rafId = requestAnimationFrame(loop);
|
|
14335
|
+
}
|
|
14336
|
+
flushPendingVisibilityMutations() {
|
|
14337
|
+
if (this.disabled) return;
|
|
14338
|
+
if (this.frozen || this.locked || this.elements.size === 0) return;
|
|
14339
|
+
const state = computeVisibility(this.elements, this.previousState, {
|
|
14340
|
+
root: this.root,
|
|
14341
|
+
threshold: this.threshold,
|
|
14342
|
+
sensitivity: this.sensitivity,
|
|
14343
|
+
rootMargin: this.rootMargin
|
|
14344
|
+
});
|
|
14345
|
+
for (const [el, entry] of state.entries()) {
|
|
14346
|
+
const old = this.previousState.get(el);
|
|
14347
|
+
const changed = !old || old.isVisible !== entry.isVisible || Math.abs(old.intersectionRatio - entry.intersectionRatio) > this.sensitivity;
|
|
14348
|
+
if (changed) {
|
|
14349
|
+
const id = this.mirror.getId(el);
|
|
14350
|
+
if (id !== -1) {
|
|
14351
|
+
this.buffer.set(el, {
|
|
14352
|
+
id,
|
|
14353
|
+
isVisible: entry.isVisible,
|
|
14354
|
+
ratio: entry.intersectionRatio
|
|
14355
|
+
});
|
|
14356
|
+
}
|
|
14357
|
+
this.previousState.set(el, entry);
|
|
14358
|
+
}
|
|
14359
|
+
}
|
|
14360
|
+
this.previousState = state;
|
|
14361
|
+
if (!this.hasInitialized) {
|
|
14362
|
+
this.hasInitialized = true;
|
|
14363
|
+
this.buffer.clear();
|
|
14364
|
+
return;
|
|
14365
|
+
}
|
|
14366
|
+
this.scheduleEmit();
|
|
14367
|
+
}
|
|
14368
|
+
scheduleEmit() {
|
|
14369
|
+
if (this.mode === "debounce") {
|
|
14370
|
+
clearTimeout(this.debounceTimer);
|
|
14371
|
+
this.debounceTimer = setTimeout(() => this.flushBuffer(), this.debounce);
|
|
14372
|
+
} else if (this.mode === "throttle") {
|
|
14373
|
+
const now = performance.now();
|
|
14374
|
+
if (now - this.lastThrottleTime >= this.throttle) {
|
|
14375
|
+
this.lastThrottleTime = now;
|
|
14376
|
+
this.flushBuffer();
|
|
14377
|
+
}
|
|
14378
|
+
} else {
|
|
14379
|
+
this.flushBuffer();
|
|
14380
|
+
}
|
|
14381
|
+
}
|
|
14382
|
+
flushBuffer() {
|
|
14383
|
+
var _a2;
|
|
14384
|
+
if (this.buffer.size === 0) return;
|
|
14385
|
+
(_a2 = this.notifyActivity) == null ? void 0 : _a2.call(this, this.buffer.size);
|
|
14386
|
+
this.mutationCb({ mutations: Array.from(this.buffer.values()) });
|
|
14387
|
+
this.buffer.clear();
|
|
14388
|
+
}
|
|
14389
|
+
observe(el) {
|
|
14390
|
+
if (this.disabled) return;
|
|
14391
|
+
this.elements.add(el);
|
|
14392
|
+
}
|
|
14393
|
+
unobserve(el) {
|
|
14394
|
+
if (this.disabled) return;
|
|
14395
|
+
this.elements.delete(el);
|
|
14396
|
+
this.previousState.delete(el);
|
|
14397
|
+
this.pending.delete(el);
|
|
14398
|
+
}
|
|
14399
|
+
freeze() {
|
|
14400
|
+
this.frozen = true;
|
|
14401
|
+
}
|
|
14402
|
+
unfreeze() {
|
|
14403
|
+
this.frozen = false;
|
|
14404
|
+
}
|
|
14405
|
+
lock() {
|
|
14406
|
+
this.locked = true;
|
|
14407
|
+
}
|
|
14408
|
+
unlock() {
|
|
14409
|
+
this.locked = false;
|
|
14410
|
+
}
|
|
14411
|
+
reset() {
|
|
14412
|
+
this.elements.clear();
|
|
14413
|
+
this.previousState.clear();
|
|
14414
|
+
this.pending.clear();
|
|
14415
|
+
if (this.rafId) cancelAnimationFrame(this.rafId);
|
|
14416
|
+
}
|
|
14417
|
+
}
|
|
14024
14418
|
let wrappedEmit;
|
|
14025
14419
|
let takeFullSnapshot$1;
|
|
14026
14420
|
let canvasManager;
|
|
14421
|
+
let visibilityManager;
|
|
14027
14422
|
let recording = false;
|
|
14028
|
-
const
|
|
14423
|
+
const customEventQueue = [];
|
|
14424
|
+
let flushCustomEventQueue;
|
|
14029
14425
|
try {
|
|
14030
14426
|
if (Array.from([1], (x2) => x2 * 2)[0] !== 2) {
|
|
14031
14427
|
const cleanFrame = document.createElement("iframe");
|
|
@@ -14042,12 +14438,12 @@ function record(options = {}) {
|
|
|
14042
14438
|
emit,
|
|
14043
14439
|
checkoutEveryNms,
|
|
14044
14440
|
checkoutEveryNth,
|
|
14441
|
+
checkoutEveryNvm,
|
|
14045
14442
|
blockClass = "rr-block",
|
|
14046
14443
|
blockSelector = null,
|
|
14047
14444
|
ignoreClass = "rr-ignore",
|
|
14048
14445
|
ignoreSelector = null,
|
|
14049
14446
|
excludeAttribute: _excludeAttribute,
|
|
14050
|
-
includeAttribute: _includeAttribute,
|
|
14051
14447
|
maskTextClass = "rr-mask",
|
|
14052
14448
|
maskTextSelector = null,
|
|
14053
14449
|
inlineStylesheet = true,
|
|
@@ -14065,7 +14461,7 @@ function record(options = {}) {
|
|
|
14065
14461
|
recordCanvas = false,
|
|
14066
14462
|
recordCrossOriginIframes = false,
|
|
14067
14463
|
recordAfter = options.recordAfter === "DOMContentLoaded" ? options.recordAfter : "load",
|
|
14068
|
-
|
|
14464
|
+
flushCustomEvent = options.flushCustomEvent !== void 0 ? options.flushCustomEvent : "after",
|
|
14069
14465
|
userTriggeredOnInput = false,
|
|
14070
14466
|
collectFonts = false,
|
|
14071
14467
|
inlineImages = false,
|
|
@@ -14097,8 +14493,7 @@ function record(options = {}) {
|
|
|
14097
14493
|
sampling.mousemove = mousemoveWait;
|
|
14098
14494
|
}
|
|
14099
14495
|
mirror.reset();
|
|
14100
|
-
const excludeAttribute = _excludeAttribute === void 0 ?
|
|
14101
|
-
const includeAttribute = _includeAttribute === void 0 ? /.+/i : _includeAttribute;
|
|
14496
|
+
const excludeAttribute = _excludeAttribute === void 0 ? /.^/ : _excludeAttribute;
|
|
14102
14497
|
const maskInputOptions = maskAllInputs === true ? {
|
|
14103
14498
|
color: true,
|
|
14104
14499
|
date: true,
|
|
@@ -14135,6 +14530,10 @@ function record(options = {}) {
|
|
|
14135
14530
|
polyfill$1();
|
|
14136
14531
|
let lastFullSnapshotEvent;
|
|
14137
14532
|
let incrementalSnapshotCount = 0;
|
|
14533
|
+
let recentVisibilityChanges = 0;
|
|
14534
|
+
const onVisibilityActivity = (count) => {
|
|
14535
|
+
recentVisibilityChanges += count;
|
|
14536
|
+
};
|
|
14138
14537
|
const eventProcessor = (e2) => {
|
|
14139
14538
|
for (const plugin3 of plugins || []) {
|
|
14140
14539
|
if (plugin3.eventProcessor) {
|
|
@@ -14175,7 +14574,11 @@ function record(options = {}) {
|
|
|
14175
14574
|
incrementalSnapshotCount++;
|
|
14176
14575
|
const exceedCount = checkoutEveryNth && incrementalSnapshotCount >= checkoutEveryNth;
|
|
14177
14576
|
const exceedTime = checkoutEveryNms && e2.timestamp - lastFullSnapshotEvent.timestamp > checkoutEveryNms;
|
|
14178
|
-
|
|
14577
|
+
const exceedVisibility = checkoutEveryNvm && recentVisibilityChanges >= checkoutEveryNvm;
|
|
14578
|
+
if (exceedCount || exceedTime || exceedVisibility) {
|
|
14579
|
+
if (exceedVisibility) {
|
|
14580
|
+
recentVisibilityChanges = 0;
|
|
14581
|
+
}
|
|
14179
14582
|
takeFullSnapshot$1(true);
|
|
14180
14583
|
}
|
|
14181
14584
|
}
|
|
@@ -14203,6 +14606,17 @@ function record(options = {}) {
|
|
|
14203
14606
|
...p
|
|
14204
14607
|
}
|
|
14205
14608
|
});
|
|
14609
|
+
const wrappedVisibilityMutationEmit = (p) => {
|
|
14610
|
+
var _a2;
|
|
14611
|
+
(_a2 = hooks == null ? void 0 : hooks.visibilityMutation) == null ? void 0 : _a2.call(hooks, p);
|
|
14612
|
+
wrappedEmit({
|
|
14613
|
+
type: EventType.IncrementalSnapshot,
|
|
14614
|
+
data: {
|
|
14615
|
+
source: IncrementalSource.VisibilityMutation,
|
|
14616
|
+
...p
|
|
14617
|
+
}
|
|
14618
|
+
});
|
|
14619
|
+
};
|
|
14206
14620
|
const wrappedAdoptedStyleSheetEmit = (a2) => wrappedEmit({
|
|
14207
14621
|
type: EventType.IncrementalSnapshot,
|
|
14208
14622
|
data: {
|
|
@@ -14240,6 +14654,13 @@ function record(options = {}) {
|
|
|
14240
14654
|
sampling: sampling.canvas,
|
|
14241
14655
|
dataURLOptions
|
|
14242
14656
|
});
|
|
14657
|
+
visibilityManager = new VisibilityManager({
|
|
14658
|
+
doc: window.document,
|
|
14659
|
+
mirror,
|
|
14660
|
+
sampling: sampling.visibility,
|
|
14661
|
+
mutationCb: wrappedVisibilityMutationEmit,
|
|
14662
|
+
notifyActivity: onVisibilityActivity
|
|
14663
|
+
});
|
|
14243
14664
|
const shadowDomManager = new ShadowDomManager({
|
|
14244
14665
|
mutationCb: wrappedMutationEmit,
|
|
14245
14666
|
scrollCb: wrappedScrollEmit,
|
|
@@ -14249,7 +14670,6 @@ function record(options = {}) {
|
|
|
14249
14670
|
maskTextClass,
|
|
14250
14671
|
maskTextSelector,
|
|
14251
14672
|
excludeAttribute,
|
|
14252
|
-
includeAttribute,
|
|
14253
14673
|
inlineStylesheet,
|
|
14254
14674
|
maskInputOptions,
|
|
14255
14675
|
dataURLOptions,
|
|
@@ -14262,6 +14682,7 @@ function record(options = {}) {
|
|
|
14262
14682
|
iframeManager,
|
|
14263
14683
|
stylesheetManager,
|
|
14264
14684
|
canvasManager,
|
|
14685
|
+
visibilityManager,
|
|
14265
14686
|
keepIframeSrcFn,
|
|
14266
14687
|
processedNodeManager
|
|
14267
14688
|
},
|
|
@@ -14292,7 +14713,6 @@ function record(options = {}) {
|
|
|
14292
14713
|
maskTextClass,
|
|
14293
14714
|
maskTextSelector,
|
|
14294
14715
|
excludeAttribute,
|
|
14295
|
-
includeAttribute,
|
|
14296
14716
|
inlineStylesheet,
|
|
14297
14717
|
maskAllInputs: maskInputOptions,
|
|
14298
14718
|
maskTextFn,
|
|
@@ -14341,6 +14761,12 @@ function record(options = {}) {
|
|
|
14341
14761
|
mirror.getId(document)
|
|
14342
14762
|
);
|
|
14343
14763
|
};
|
|
14764
|
+
flushCustomEventQueue = () => {
|
|
14765
|
+
for (const e2 of customEventQueue) {
|
|
14766
|
+
wrappedEmit(e2);
|
|
14767
|
+
}
|
|
14768
|
+
customEventQueue.length = 0;
|
|
14769
|
+
};
|
|
14344
14770
|
try {
|
|
14345
14771
|
const handlers = [];
|
|
14346
14772
|
const observe = (doc) => {
|
|
@@ -14399,6 +14825,7 @@ function record(options = {}) {
|
|
|
14399
14825
|
}
|
|
14400
14826
|
}),
|
|
14401
14827
|
canvasMutationCb: wrappedCanvasMutationEmit,
|
|
14828
|
+
visibilityMutationCb: wrappedVisibilityMutationEmit,
|
|
14402
14829
|
fontCb: (p) => wrappedEmit({
|
|
14403
14830
|
type: EventType.IncrementalSnapshot,
|
|
14404
14831
|
data: {
|
|
@@ -14430,7 +14857,6 @@ function record(options = {}) {
|
|
|
14430
14857
|
maskTextClass,
|
|
14431
14858
|
maskTextSelector,
|
|
14432
14859
|
excludeAttribute,
|
|
14433
|
-
includeAttribute,
|
|
14434
14860
|
maskInputOptions,
|
|
14435
14861
|
inlineStylesheet,
|
|
14436
14862
|
sampling,
|
|
@@ -14452,6 +14878,7 @@ function record(options = {}) {
|
|
|
14452
14878
|
shadowDomManager,
|
|
14453
14879
|
processedNodeManager,
|
|
14454
14880
|
canvasManager,
|
|
14881
|
+
visibilityManager,
|
|
14455
14882
|
ignoreCSSAttributes,
|
|
14456
14883
|
plugins: ((_a2 = plugins == null ? void 0 : plugins.filter((p) => p.observer)) == null ? void 0 : _a2.map((p) => ({
|
|
14457
14884
|
observer: p.observer,
|
|
@@ -14476,14 +14903,14 @@ function record(options = {}) {
|
|
|
14476
14903
|
}
|
|
14477
14904
|
});
|
|
14478
14905
|
const init = () => {
|
|
14479
|
-
if (
|
|
14480
|
-
|
|
14906
|
+
if (flushCustomEvent === "before") {
|
|
14907
|
+
flushCustomEventQueue();
|
|
14481
14908
|
}
|
|
14482
14909
|
takeFullSnapshot$1();
|
|
14483
14910
|
handlers.push(observe(document));
|
|
14484
14911
|
recording = true;
|
|
14485
|
-
if (
|
|
14486
|
-
|
|
14912
|
+
if (flushCustomEvent === "after") {
|
|
14913
|
+
flushCustomEventQueue();
|
|
14487
14914
|
}
|
|
14488
14915
|
};
|
|
14489
14916
|
if (document.readyState === "interactive" || document.readyState === "complete") {
|
|
@@ -14513,7 +14940,7 @@ function record(options = {}) {
|
|
|
14513
14940
|
);
|
|
14514
14941
|
}
|
|
14515
14942
|
return () => {
|
|
14516
|
-
|
|
14943
|
+
flushCustomEventQueue();
|
|
14517
14944
|
handlers.forEach((h) => h());
|
|
14518
14945
|
processedNodeManager.destroy();
|
|
14519
14946
|
recording = false;
|
|
@@ -14523,12 +14950,10 @@ function record(options = {}) {
|
|
|
14523
14950
|
console.warn(error);
|
|
14524
14951
|
}
|
|
14525
14952
|
}
|
|
14526
|
-
|
|
14527
|
-
|
|
14528
|
-
|
|
14529
|
-
|
|
14530
|
-
preRecordingCustomEvents.length = 0;
|
|
14531
|
-
}
|
|
14953
|
+
record.flushCustomEventQueue = () => {
|
|
14954
|
+
console.warn(`[rrweb] CustomEvent flushing: ${customEventQueue.length} events`);
|
|
14955
|
+
flushCustomEventQueue();
|
|
14956
|
+
};
|
|
14532
14957
|
record.addCustomEvent = (tag, payload) => {
|
|
14533
14958
|
const customEvent = {
|
|
14534
14959
|
type: EventType.Custom,
|
|
@@ -14538,8 +14963,8 @@ record.addCustomEvent = (tag, payload) => {
|
|
|
14538
14963
|
}
|
|
14539
14964
|
};
|
|
14540
14965
|
if (!recording) {
|
|
14541
|
-
console.warn(`[rrweb] CustomEvent buffered before recording start: ${tag}`);
|
|
14542
|
-
|
|
14966
|
+
console.warn(`[rrweb] CustomEvent buffered before/after recording start: ${tag}`);
|
|
14967
|
+
customEventQueue.push(customEvent);
|
|
14543
14968
|
return;
|
|
14544
14969
|
}
|
|
14545
14970
|
wrappedEmit(customEvent);
|