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