rrweb
Version:
record and replay the web
1,308 lines (1,303 loc) • 160 kB
JavaScript
'use strict';
var NodeType;
(function (NodeType) {
NodeType[NodeType["Document"] = 0] = "Document";
NodeType[NodeType["DocumentType"] = 1] = "DocumentType";
NodeType[NodeType["Element"] = 2] = "Element";
NodeType[NodeType["Text"] = 3] = "Text";
NodeType[NodeType["CDATA"] = 4] = "CDATA";
NodeType[NodeType["Comment"] = 5] = "Comment";
})(NodeType || (NodeType = {}));
function isElement(n) {
return n.nodeType === n.ELEMENT_NODE;
}
function isShadowRoot(n) {
var host = n === null || n === void 0 ? void 0 : n.host;
return Boolean((host === null || host === void 0 ? void 0 : host.shadowRoot) === n);
}
function isNativeShadowDom(shadowRoot) {
return Object.prototype.toString.call(shadowRoot) === '[object ShadowRoot]';
}
function fixBrowserCompatibilityIssuesInCSS(cssText) {
if (cssText.includes(' background-clip: text;') &&
!cssText.includes(' -webkit-background-clip: text;')) {
cssText = cssText.replace(' background-clip: text;', ' -webkit-background-clip: text; background-clip: text;');
}
return cssText;
}
function getCssRulesString(s) {
try {
var rules = s.rules || s.cssRules;
return rules
? fixBrowserCompatibilityIssuesInCSS(Array.from(rules).map(getCssRuleString).join(''))
: null;
}
catch (error) {
return null;
}
}
function getCssRuleString(rule) {
var cssStringified = rule.cssText;
if (isCSSImportRule(rule)) {
try {
cssStringified = getCssRulesString(rule.styleSheet) || cssStringified;
}
catch (_a) {
}
}
return cssStringified;
}
function isCSSImportRule(rule) {
return 'styleSheet' in rule;
}
var Mirror = (function () {
function Mirror() {
this.idNodeMap = new Map();
this.nodeMetaMap = new WeakMap();
}
Mirror.prototype.getId = function (n) {
var _a;
if (!n)
return -1;
var id = (_a = this.getMeta(n)) === null || _a === void 0 ? void 0 : _a.id;
return id !== null && id !== void 0 ? id : -1;
};
Mirror.prototype.getNode = function (id) {
return this.idNodeMap.get(id) || null;
};
Mirror.prototype.getIds = function () {
return Array.from(this.idNodeMap.keys());
};
Mirror.prototype.getMeta = function (n) {
return this.nodeMetaMap.get(n) || null;
};
Mirror.prototype.removeNodeFromMap = function (n) {
var _this = this;
var id = this.getId(n);
this.idNodeMap["delete"](id);
if (n.childNodes) {
n.childNodes.forEach(function (childNode) {
return _this.removeNodeFromMap(childNode);
});
}
};
Mirror.prototype.has = function (id) {
return this.idNodeMap.has(id);
};
Mirror.prototype.hasNode = function (node) {
return this.nodeMetaMap.has(node);
};
Mirror.prototype.add = function (n, meta) {
var id = meta.id;
this.idNodeMap.set(id, n);
this.nodeMetaMap.set(n, meta);
};
Mirror.prototype.replace = function (id, n) {
var oldNode = this.getNode(id);
if (oldNode) {
var meta = this.nodeMetaMap.get(oldNode);
if (meta)
this.nodeMetaMap.set(n, meta);
}
this.idNodeMap.set(id, n);
};
Mirror.prototype.reset = function () {
this.idNodeMap = new Map();
this.nodeMetaMap = new WeakMap();
};
return Mirror;
}());
function createMirror() {
return new Mirror();
}
function maskInputValue(_a) {
var maskInputOptions = _a.maskInputOptions, tagName = _a.tagName, type = _a.type, value = _a.value, maskInputFn = _a.maskInputFn;
var text = value || '';
if (maskInputOptions[tagName.toLowerCase()] ||
maskInputOptions[type]) {
if (maskInputFn) {
text = maskInputFn(text);
}
else {
text = '*'.repeat(text.length);
}
}
return text;
}
var ORIGINAL_ATTRIBUTE_NAME = '__rrweb_original__';
function is2DCanvasBlank(canvas) {
var ctx = canvas.getContext('2d');
if (!ctx)
return true;
var chunkSize = 50;
for (var x = 0; x < canvas.width; x += chunkSize) {
for (var y = 0; y < canvas.height; y += chunkSize) {
var getImageData = ctx.getImageData;
var originalGetImageData = ORIGINAL_ATTRIBUTE_NAME in getImageData
? getImageData[ORIGINAL_ATTRIBUTE_NAME]
: getImageData;
var pixelBuffer = new Uint32Array(originalGetImageData.call(ctx, x, y, Math.min(chunkSize, canvas.width - x), Math.min(chunkSize, canvas.height - y)).data.buffer);
if (pixelBuffer.some(function (pixel) { return pixel !== 0; }))
return false;
}
}
return true;
}
var _id = 1;
var tagNameRegex = new RegExp('[^a-z0-9-_:]');
var IGNORED_NODE = -2;
function genId() {
return _id++;
}
function getValidTagName(element) {
if (element instanceof HTMLFormElement) {
return 'form';
}
var processedTagName = element.tagName.toLowerCase().trim();
if (tagNameRegex.test(processedTagName)) {
return 'div';
}
return processedTagName;
}
function stringifyStyleSheet(sheet) {
return sheet.cssRules
? Array.from(sheet.cssRules)
.map(function (rule) { return rule.cssText || ''; })
.join('')
: '';
}
function extractOrigin(url) {
var origin = '';
if (url.indexOf('//') > -1) {
origin = url.split('/').slice(0, 3).join('/');
}
else {
origin = url.split('/')[0];
}
origin = origin.split('?')[0];
return origin;
}
var canvasService;
var canvasCtx;
var URL_IN_CSS_REF = /url\((?:(')([^']*)'|(")(.*?)"|([^)]*))\)/gm;
var RELATIVE_PATH = /^(?!www\.|(?:http|ftp)s?:\/\/|[A-Za-z]:\\|\/\/|#).*/;
var DATA_URI = /^(data:)([^,]*),(.*)/i;
function absoluteToStylesheet(cssText, href) {
return (cssText || '').replace(URL_IN_CSS_REF, function (origin, quote1, path1, quote2, path2, path3) {
var filePath = path1 || path2 || path3;
var maybeQuote = quote1 || quote2 || '';
if (!filePath) {
return origin;
}
if (!RELATIVE_PATH.test(filePath)) {
return "url(".concat(maybeQuote).concat(filePath).concat(maybeQuote, ")");
}
if (DATA_URI.test(filePath)) {
return "url(".concat(maybeQuote).concat(filePath).concat(maybeQuote, ")");
}
if (filePath[0] === '/') {
return "url(".concat(maybeQuote).concat(extractOrigin(href) + filePath).concat(maybeQuote, ")");
}
var stack = href.split('/');
var parts = filePath.split('/');
stack.pop();
for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) {
var part = parts_1[_i];
if (part === '.') {
continue;
}
else if (part === '..') {
stack.pop();
}
else {
stack.push(part);
}
}
return "url(".concat(maybeQuote).concat(stack.join('/')).concat(maybeQuote, ")");
});
}
var SRCSET_NOT_SPACES = /^[^ \t\n\r\u000c]+/;
var SRCSET_COMMAS_OR_SPACES = /^[, \t\n\r\u000c]+/;
function getAbsoluteSrcsetString(doc, attributeValue) {
if (attributeValue.trim() === '') {
return attributeValue;
}
var pos = 0;
function collectCharacters(regEx) {
var chars;
var match = regEx.exec(attributeValue.substring(pos));
if (match) {
chars = match[0];
pos += chars.length;
return chars;
}
return '';
}
var output = [];
while (true) {
collectCharacters(SRCSET_COMMAS_OR_SPACES);
if (pos >= attributeValue.length) {
break;
}
var url = collectCharacters(SRCSET_NOT_SPACES);
if (url.slice(-1) === ',') {
url = absoluteToDoc(doc, url.substring(0, url.length - 1));
output.push(url);
}
else {
var descriptorsStr = '';
url = absoluteToDoc(doc, url);
var inParens = false;
while (true) {
var c = attributeValue.charAt(pos);
if (c === '') {
output.push((url + descriptorsStr).trim());
break;
}
else if (!inParens) {
if (c === ',') {
pos += 1;
output.push((url + descriptorsStr).trim());
break;
}
else if (c === '(') {
inParens = true;
}
}
else {
if (c === ')') {
inParens = false;
}
}
descriptorsStr += c;
pos += 1;
}
}
}
return output.join(', ');
}
function absoluteToDoc(doc, attributeValue) {
if (!attributeValue || attributeValue.trim() === '') {
return attributeValue;
}
var a = doc.createElement('a');
a.href = attributeValue;
return a.href;
}
function isSVGElement(el) {
return Boolean(el.tagName === 'svg' || el.ownerSVGElement);
}
function getHref() {
var a = document.createElement('a');
a.href = '';
return a.href;
}
function transformAttribute(doc, tagName, name, value) {
if (name === 'src' ||
(name === 'href' && value && !(tagName === 'use' && value[0] === '#'))) {
return absoluteToDoc(doc, value);
}
else if (name === 'xlink:href' && value && value[0] !== '#') {
return absoluteToDoc(doc, value);
}
else if (name === 'background' &&
value &&
(tagName === 'table' || tagName === 'td' || tagName === 'th')) {
return absoluteToDoc(doc, value);
}
else if (name === 'srcset' && value) {
return getAbsoluteSrcsetString(doc, value);
}
else if (name === 'style' && value) {
return absoluteToStylesheet(value, getHref());
}
else if (tagName === 'object' && name === 'data' && value) {
return absoluteToDoc(doc, value);
}
else {
return value;
}
}
function _isBlockedElement(element, blockClass, blockSelector) {
if (typeof blockClass === 'string') {
if (element.classList.contains(blockClass)) {
return true;
}
}
else {
for (var eIndex = element.classList.length; eIndex--;) {
var className = element.classList[eIndex];
if (blockClass.test(className)) {
return true;
}
}
}
if (blockSelector) {
return element.matches(blockSelector);
}
return false;
}
function classMatchesRegex(node, regex, checkAncestors) {
if (!node)
return false;
if (node.nodeType !== node.ELEMENT_NODE) {
if (!checkAncestors)
return false;
return classMatchesRegex(node.parentNode, regex, checkAncestors);
}
for (var eIndex = node.classList.length; eIndex--;) {
var className = node.classList[eIndex];
if (regex.test(className)) {
return true;
}
}
if (!checkAncestors)
return false;
return classMatchesRegex(node.parentNode, regex, checkAncestors);
}
function needMaskingText(node, maskTextClass, maskTextSelector) {
var el = node.nodeType === node.ELEMENT_NODE
? node
: node.parentElement;
if (el === null)
return false;
if (typeof maskTextClass === 'string') {
if (el.classList.contains(maskTextClass))
return true;
if (el.closest(".".concat(maskTextClass)))
return true;
}
else {
if (classMatchesRegex(el, maskTextClass, true))
return true;
}
if (maskTextSelector) {
if (el.matches(maskTextSelector))
return true;
if (el.closest(maskTextSelector))
return true;
}
return false;
}
function onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) {
var win = iframeEl.contentWindow;
if (!win) {
return;
}
var fired = false;
var readyState;
try {
readyState = win.document.readyState;
}
catch (error) {
return;
}
if (readyState !== 'complete') {
var timer_1 = setTimeout(function () {
if (!fired) {
listener();
fired = true;
}
}, iframeLoadTimeout);
iframeEl.addEventListener('load', function () {
clearTimeout(timer_1);
fired = true;
listener();
});
return;
}
var blankUrl = 'about:blank';
if (win.location.href !== blankUrl ||
iframeEl.src === blankUrl ||
iframeEl.src === '') {
setTimeout(listener, 0);
return iframeEl.addEventListener('load', listener);
}
iframeEl.addEventListener('load', listener);
}
function onceStylesheetLoaded(link, listener, styleSheetLoadTimeout) {
var fired = false;
var styleSheetLoaded;
try {
styleSheetLoaded = link.sheet;
}
catch (error) {
return;
}
if (styleSheetLoaded)
return;
var timer = setTimeout(function () {
if (!fired) {
listener();
fired = true;
}
}, styleSheetLoadTimeout);
link.addEventListener('load', function () {
clearTimeout(timer);
fired = true;
listener();
});
}
function serializeNode(n, options) {
var doc = options.doc, mirror = options.mirror, blockClass = options.blockClass, blockSelector = options.blockSelector, maskTextClass = options.maskTextClass, maskTextSelector = options.maskTextSelector, inlineStylesheet = options.inlineStylesheet, _a = options.maskInputOptions, maskInputOptions = _a === void 0 ? {} : _a, maskTextFn = options.maskTextFn, maskInputFn = options.maskInputFn, _b = options.dataURLOptions, dataURLOptions = _b === void 0 ? {} : _b, inlineImages = options.inlineImages, recordCanvas = options.recordCanvas, keepIframeSrcFn = options.keepIframeSrcFn, _c = options.newlyAddedElement, newlyAddedElement = _c === void 0 ? false : _c;
var rootId = getRootId(doc, mirror);
switch (n.nodeType) {
case n.DOCUMENT_NODE:
if (n.compatMode !== 'CSS1Compat') {
return {
type: NodeType.Document,
childNodes: [],
compatMode: n.compatMode
};
}
else {
return {
type: NodeType.Document,
childNodes: []
};
}
case n.DOCUMENT_TYPE_NODE:
return {
type: NodeType.DocumentType,
name: n.name,
publicId: n.publicId,
systemId: n.systemId,
rootId: rootId
};
case n.ELEMENT_NODE:
return serializeElementNode(n, {
doc: doc,
blockClass: blockClass,
blockSelector: blockSelector,
inlineStylesheet: inlineStylesheet,
maskInputOptions: maskInputOptions,
maskInputFn: maskInputFn,
dataURLOptions: dataURLOptions,
inlineImages: inlineImages,
recordCanvas: recordCanvas,
keepIframeSrcFn: keepIframeSrcFn,
newlyAddedElement: newlyAddedElement,
rootId: rootId
});
case n.TEXT_NODE:
return serializeTextNode(n, {
maskTextClass: maskTextClass,
maskTextSelector: maskTextSelector,
maskTextFn: maskTextFn,
rootId: rootId
});
case n.CDATA_SECTION_NODE:
return {
type: NodeType.CDATA,
textContent: '',
rootId: rootId
};
case n.COMMENT_NODE:
return {
type: NodeType.Comment,
textContent: n.textContent || '',
rootId: rootId
};
default:
return false;
}
}
function getRootId(doc, mirror) {
if (!mirror.hasNode(doc))
return undefined;
var docId = mirror.getId(doc);
return docId === 1 ? undefined : docId;
}
function serializeTextNode(n, options) {
var _a;
var maskTextClass = options.maskTextClass, maskTextSelector = options.maskTextSelector, maskTextFn = options.maskTextFn, rootId = options.rootId;
var parentTagName = n.parentNode && n.parentNode.tagName;
var textContent = n.textContent;
var isStyle = parentTagName === 'STYLE' ? true : undefined;
var isScript = parentTagName === 'SCRIPT' ? true : undefined;
if (isStyle && textContent) {
try {
if (n.nextSibling || n.previousSibling) {
}
else if ((_a = n.parentNode.sheet) === null || _a === void 0 ? void 0 : _a.cssRules) {
textContent = stringifyStyleSheet(n.parentNode.sheet);
}
}
catch (err) {
console.warn("Cannot get CSS styles from text's parentNode. Error: ".concat(err), n);
}
textContent = absoluteToStylesheet(textContent, getHref());
}
if (isScript) {
textContent = 'SCRIPT_PLACEHOLDER';
}
if (!isStyle &&
!isScript &&
textContent &&
needMaskingText(n, maskTextClass, maskTextSelector)) {
textContent = maskTextFn
? maskTextFn(textContent)
: textContent.replace(/[\S]/g, '*');
}
return {
type: NodeType.Text,
textContent: textContent || '',
isStyle: isStyle,
rootId: rootId
};
}
function serializeElementNode(n, options) {
var doc = options.doc, blockClass = options.blockClass, blockSelector = options.blockSelector, inlineStylesheet = options.inlineStylesheet, _a = options.maskInputOptions, maskInputOptions = _a === void 0 ? {} : _a, maskInputFn = options.maskInputFn, _b = options.dataURLOptions, dataURLOptions = _b === void 0 ? {} : _b, inlineImages = options.inlineImages, recordCanvas = options.recordCanvas, keepIframeSrcFn = options.keepIframeSrcFn, _c = options.newlyAddedElement, newlyAddedElement = _c === void 0 ? false : _c, rootId = options.rootId;
var needBlock = _isBlockedElement(n, blockClass, blockSelector);
var tagName = getValidTagName(n);
var attributes = {};
var len = n.attributes.length;
for (var i = 0; i < len; i++) {
var attr = n.attributes[i];
attributes[attr.name] = transformAttribute(doc, tagName, attr.name, attr.value);
}
if (tagName === 'link' && inlineStylesheet) {
var stylesheet = Array.from(doc.styleSheets).find(function (s) {
return s.href === n.href;
});
var cssText = null;
if (stylesheet) {
cssText = getCssRulesString(stylesheet);
}
if (cssText) {
delete attributes.rel;
delete attributes.href;
attributes._cssText = absoluteToStylesheet(cssText, stylesheet.href);
}
}
if (tagName === 'style' &&
n.sheet &&
!(n.innerText || n.textContent || '').trim().length) {
var cssText = getCssRulesString(n.sheet);
if (cssText) {
attributes._cssText = absoluteToStylesheet(cssText, getHref());
}
}
if (tagName === 'input' || tagName === 'textarea' || tagName === 'select') {
var value = n.value;
var checked = n.checked;
if (attributes.type !== 'radio' &&
attributes.type !== 'checkbox' &&
attributes.type !== 'submit' &&
attributes.type !== 'button' &&
value) {
attributes.value = maskInputValue({
type: attributes.type,
tagName: tagName,
value: value,
maskInputOptions: maskInputOptions,
maskInputFn: maskInputFn
});
}
else if (checked) {
attributes.checked = checked;
}
}
if (tagName === 'option') {
if (n.selected && !maskInputOptions['select']) {
attributes.selected = true;
}
else {
delete attributes.selected;
}
}
if (tagName === 'canvas' && recordCanvas) {
if (n.__context === '2d') {
if (!is2DCanvasBlank(n)) {
attributes.rr_dataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);
}
}
else if (!('__context' in n)) {
var canvasDataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);
var blankCanvas = document.createElement('canvas');
blankCanvas.width = n.width;
blankCanvas.height = n.height;
var blankCanvasDataURL = blankCanvas.toDataURL(dataURLOptions.type, dataURLOptions.quality);
if (canvasDataURL !== blankCanvasDataURL) {
attributes.rr_dataURL = canvasDataURL;
}
}
}
if (tagName === 'img' && inlineImages) {
if (!canvasService) {
canvasService = doc.createElement('canvas');
canvasCtx = canvasService.getContext('2d');
}
var image_1 = n;
var oldValue_1 = image_1.crossOrigin;
image_1.crossOrigin = 'anonymous';
var recordInlineImage = function () {
try {
canvasService.width = image_1.naturalWidth;
canvasService.height = image_1.naturalHeight;
canvasCtx.drawImage(image_1, 0, 0);
attributes.rr_dataURL = canvasService.toDataURL(dataURLOptions.type, dataURLOptions.quality);
}
catch (err) {
console.warn("Cannot inline img src=".concat(image_1.currentSrc, "! Error: ").concat(err));
}
oldValue_1
? (attributes.crossOrigin = oldValue_1)
: image_1.removeAttribute('crossorigin');
};
if (image_1.complete && image_1.naturalWidth !== 0)
recordInlineImage();
else
image_1.onload = recordInlineImage;
}
if (tagName === 'audio' || tagName === 'video') {
attributes.rr_mediaState = n.paused
? 'paused'
: 'played';
attributes.rr_mediaCurrentTime = n.currentTime;
}
if (!newlyAddedElement) {
if (n.scrollLeft) {
attributes.rr_scrollLeft = n.scrollLeft;
}
if (n.scrollTop) {
attributes.rr_scrollTop = n.scrollTop;
}
}
if (needBlock) {
var _d = n.getBoundingClientRect(), width = _d.width, height = _d.height;
attributes = {
"class": attributes["class"],
rr_width: "".concat(width, "px"),
rr_height: "".concat(height, "px")
};
}
if (tagName === 'iframe' && !keepIframeSrcFn(attributes.src)) {
if (!n.contentDocument) {
attributes.rr_src = attributes.src;
}
delete attributes.src;
}
return {
type: NodeType.Element,
tagName: tagName,
attributes: attributes,
childNodes: [],
isSVG: isSVGElement(n) || undefined,
needBlock: needBlock,
rootId: rootId
};
}
function lowerIfExists(maybeAttr) {
if (maybeAttr === undefined) {
return '';
}
else {
return maybeAttr.toLowerCase();
}
}
function slimDOMExcluded(sn, slimDOMOptions) {
if (slimDOMOptions.comment && sn.type === NodeType.Comment) {
return true;
}
else if (sn.type === NodeType.Element) {
if (slimDOMOptions.script &&
(sn.tagName === 'script' ||
(sn.tagName === 'link' &&
sn.attributes.rel === 'preload' &&
sn.attributes.as === 'script') ||
(sn.tagName === 'link' &&
sn.attributes.rel === 'prefetch' &&
typeof sn.attributes.href === 'string' &&
sn.attributes.href.endsWith('.js')))) {
return true;
}
else if (slimDOMOptions.headFavicon &&
((sn.tagName === 'link' && sn.attributes.rel === 'shortcut icon') ||
(sn.tagName === 'meta' &&
(lowerIfExists(sn.attributes.name).match(/^msapplication-tile(image|color)$/) ||
lowerIfExists(sn.attributes.name) === 'application-name' ||
lowerIfExists(sn.attributes.rel) === 'icon' ||
lowerIfExists(sn.attributes.rel) === 'apple-touch-icon' ||
lowerIfExists(sn.attributes.rel) === 'shortcut icon')))) {
return true;
}
else if (sn.tagName === 'meta') {
if (slimDOMOptions.headMetaDescKeywords &&
lowerIfExists(sn.attributes.name).match(/^description|keywords$/)) {
return true;
}
else if (slimDOMOptions.headMetaSocial &&
(lowerIfExists(sn.attributes.property).match(/^(og|twitter|fb):/) ||
lowerIfExists(sn.attributes.name).match(/^(og|twitter):/) ||
lowerIfExists(sn.attributes.name) === 'pinterest')) {
return true;
}
else if (slimDOMOptions.headMetaRobots &&
(lowerIfExists(sn.attributes.name) === 'robots' ||
lowerIfExists(sn.attributes.name) === 'googlebot' ||
lowerIfExists(sn.attributes.name) === 'bingbot')) {
return true;
}
else if (slimDOMOptions.headMetaHttpEquiv &&
sn.attributes['http-equiv'] !== undefined) {
return true;
}
else if (slimDOMOptions.headMetaAuthorship &&
(lowerIfExists(sn.attributes.name) === 'author' ||
lowerIfExists(sn.attributes.name) === 'generator' ||
lowerIfExists(sn.attributes.name) === 'framework' ||
lowerIfExists(sn.attributes.name) === 'publisher' ||
lowerIfExists(sn.attributes.name) === 'progid' ||
lowerIfExists(sn.attributes.property).match(/^article:/) ||
lowerIfExists(sn.attributes.property).match(/^product:/))) {
return true;
}
else if (slimDOMOptions.headMetaVerification &&
(lowerIfExists(sn.attributes.name) === 'google-site-verification' ||
lowerIfExists(sn.attributes.name) === 'yandex-verification' ||
lowerIfExists(sn.attributes.name) === 'csrf-token' ||
lowerIfExists(sn.attributes.name) === 'p:domain_verify' ||
lowerIfExists(sn.attributes.name) === 'verify-v1' ||
lowerIfExists(sn.attributes.name) === 'verification' ||
lowerIfExists(sn.attributes.name) === 'shopify-checkout-api-token')) {
return true;
}
}
}
return false;
}
function serializeNodeWithId(n, options) {
var doc = options.doc, mirror = options.mirror, blockClass = options.blockClass, blockSelector = options.blockSelector, maskTextClass = options.maskTextClass, maskTextSelector = options.maskTextSelector, _a = options.skipChild, skipChild = _a === void 0 ? false : _a, _b = options.inlineStylesheet, inlineStylesheet = _b === void 0 ? true : _b, _c = options.maskInputOptions, maskInputOptions = _c === void 0 ? {} : _c, maskTextFn = options.maskTextFn, maskInputFn = options.maskInputFn, slimDOMOptions = options.slimDOMOptions, _d = options.dataURLOptions, dataURLOptions = _d === void 0 ? {} : _d, _e = options.inlineImages, inlineImages = _e === void 0 ? false : _e, _f = options.recordCanvas, recordCanvas = _f === void 0 ? false : _f, onSerialize = options.onSerialize, onIframeLoad = options.onIframeLoad, _g = options.iframeLoadTimeout, iframeLoadTimeout = _g === void 0 ? 5000 : _g, onStylesheetLoad = options.onStylesheetLoad, _h = options.stylesheetLoadTimeout, stylesheetLoadTimeout = _h === void 0 ? 5000 : _h, _j = options.keepIframeSrcFn, keepIframeSrcFn = _j === void 0 ? function () { return false; } : _j, _k = options.newlyAddedElement, newlyAddedElement = _k === void 0 ? false : _k;
var _l = options.preserveWhiteSpace, preserveWhiteSpace = _l === void 0 ? true : _l;
var _serializedNode = serializeNode(n, {
doc: doc,
mirror: mirror,
blockClass: blockClass,
blockSelector: blockSelector,
maskTextClass: maskTextClass,
maskTextSelector: maskTextSelector,
inlineStylesheet: inlineStylesheet,
maskInputOptions: maskInputOptions,
maskTextFn: maskTextFn,
maskInputFn: maskInputFn,
dataURLOptions: dataURLOptions,
inlineImages: inlineImages,
recordCanvas: recordCanvas,
keepIframeSrcFn: keepIframeSrcFn,
newlyAddedElement: newlyAddedElement
});
if (!_serializedNode) {
console.warn(n, 'not serialized');
return null;
}
var id;
if (mirror.hasNode(n)) {
id = mirror.getId(n);
}
else if (slimDOMExcluded(_serializedNode, slimDOMOptions) ||
(!preserveWhiteSpace &&
_serializedNode.type === NodeType.Text &&
!_serializedNode.isStyle &&
!_serializedNode.textContent.replace(/^\s+|\s+$/gm, '').length)) {
id = IGNORED_NODE;
}
else {
id = genId();
}
var serializedNode = Object.assign(_serializedNode, { id: id });
mirror.add(n, serializedNode);
if (id === IGNORED_NODE) {
return null;
}
if (onSerialize) {
onSerialize(n);
}
var recordChild = !skipChild;
if (serializedNode.type === NodeType.Element) {
recordChild = recordChild && !serializedNode.needBlock;
delete serializedNode.needBlock;
var shadowRoot = n.shadowRoot;
if (shadowRoot && isNativeShadowDom(shadowRoot))
serializedNode.isShadowHost = true;
}
if ((serializedNode.type === NodeType.Document ||
serializedNode.type === NodeType.Element) &&
recordChild) {
if (slimDOMOptions.headWhitespace &&
serializedNode.type === NodeType.Element &&
serializedNode.tagName === 'head') {
preserveWhiteSpace = false;
}
var bypassOptions = {
doc: doc,
mirror: mirror,
blockClass: blockClass,
blockSelector: blockSelector,
maskTextClass: maskTextClass,
maskTextSelector: maskTextSelector,
skipChild: skipChild,
inlineStylesheet: inlineStylesheet,
maskInputOptions: maskInputOptions,
maskTextFn: maskTextFn,
maskInputFn: maskInputFn,
slimDOMOptions: slimDOMOptions,
dataURLOptions: dataURLOptions,
inlineImages: inlineImages,
recordCanvas: recordCanvas,
preserveWhiteSpace: preserveWhiteSpace,
onSerialize: onSerialize,
onIframeLoad: onIframeLoad,
iframeLoadTimeout: iframeLoadTimeout,
onStylesheetLoad: onStylesheetLoad,
stylesheetLoadTimeout: stylesheetLoadTimeout,
keepIframeSrcFn: keepIframeSrcFn
};
for (var _i = 0, _m = Array.from(n.childNodes); _i < _m.length; _i++) {
var childN = _m[_i];
var serializedChildNode = serializeNodeWithId(childN, bypassOptions);
if (serializedChildNode) {
serializedNode.childNodes.push(serializedChildNode);
}
}
if (isElement(n) && n.shadowRoot) {
for (var _o = 0, _p = Array.from(n.shadowRoot.childNodes); _o < _p.length; _o++) {
var childN = _p[_o];
var serializedChildNode = serializeNodeWithId(childN, bypassOptions);
if (serializedChildNode) {
isNativeShadowDom(n.shadowRoot) &&
(serializedChildNode.isShadow = true);
serializedNode.childNodes.push(serializedChildNode);
}
}
}
}
if (n.parentNode &&
isShadowRoot(n.parentNode) &&
isNativeShadowDom(n.parentNode)) {
serializedNode.isShadow = true;
}
if (serializedNode.type === NodeType.Element &&
serializedNode.tagName === 'iframe') {
onceIframeLoaded(n, function () {
var iframeDoc = n.contentDocument;
if (iframeDoc && onIframeLoad) {
var serializedIframeNode = serializeNodeWithId(iframeDoc, {
doc: iframeDoc,
mirror: mirror,
blockClass: blockClass,
blockSelector: blockSelector,
maskTextClass: maskTextClass,
maskTextSelector: maskTextSelector,
skipChild: false,
inlineStylesheet: inlineStylesheet,
maskInputOptions: maskInputOptions,
maskTextFn: maskTextFn,
maskInputFn: maskInputFn,
slimDOMOptions: slimDOMOptions,
dataURLOptions: dataURLOptions,
inlineImages: inlineImages,
recordCanvas: recordCanvas,
preserveWhiteSpace: preserveWhiteSpace,
onSerialize: onSerialize,
onIframeLoad: onIframeLoad,
iframeLoadTimeout: iframeLoadTimeout,
onStylesheetLoad: onStylesheetLoad,
stylesheetLoadTimeout: stylesheetLoadTimeout,
keepIframeSrcFn: keepIframeSrcFn
});
if (serializedIframeNode) {
onIframeLoad(n, serializedIframeNode);
}
}
}, iframeLoadTimeout);
}
if (serializedNode.type === NodeType.Element &&
serializedNode.tagName === 'link' &&
serializedNode.attributes.rel === 'stylesheet') {
onceStylesheetLoaded(n, function () {
if (onStylesheetLoad) {
var serializedLinkNode = serializeNodeWithId(n, {
doc: doc,
mirror: mirror,
blockClass: blockClass,
blockSelector: blockSelector,
maskTextClass: maskTextClass,
maskTextSelector: maskTextSelector,
skipChild: false,
inlineStylesheet: inlineStylesheet,
maskInputOptions: maskInputOptions,
maskTextFn: maskTextFn,
maskInputFn: maskInputFn,
slimDOMOptions: slimDOMOptions,
dataURLOptions: dataURLOptions,
inlineImages: inlineImages,
recordCanvas: recordCanvas,
preserveWhiteSpace: preserveWhiteSpace,
onSerialize: onSerialize,
onIframeLoad: onIframeLoad,
iframeLoadTimeout: iframeLoadTimeout,
onStylesheetLoad: onStylesheetLoad,
stylesheetLoadTimeout: stylesheetLoadTimeout,
keepIframeSrcFn: keepIframeSrcFn
});
if (serializedLinkNode) {
onStylesheetLoad(n, serializedLinkNode);
}
}
}, stylesheetLoadTimeout);
}
return serializedNode;
}
function snapshot(n, options) {
var _a = options || {}, _b = _a.mirror, mirror = _b === void 0 ? new Mirror() : _b, _c = _a.blockClass, blockClass = _c === void 0 ? 'rr-block' : _c, _d = _a.blockSelector, blockSelector = _d === void 0 ? null : _d, _e = _a.maskTextClass, maskTextClass = _e === void 0 ? 'rr-mask' : _e, _f = _a.maskTextSelector, maskTextSelector = _f === void 0 ? null : _f, _g = _a.inlineStylesheet, inlineStylesheet = _g === void 0 ? true : _g, _h = _a.inlineImages, inlineImages = _h === void 0 ? false : _h, _j = _a.recordCanvas, recordCanvas = _j === void 0 ? false : _j, _k = _a.maskAllInputs, maskAllInputs = _k === void 0 ? false : _k, maskTextFn = _a.maskTextFn, maskInputFn = _a.maskInputFn, _l = _a.slimDOM, slimDOM = _l === void 0 ? false : _l, dataURLOptions = _a.dataURLOptions, preserveWhiteSpace = _a.preserveWhiteSpace, onSerialize = _a.onSerialize, onIframeLoad = _a.onIframeLoad, iframeLoadTimeout = _a.iframeLoadTimeout, onStylesheetLoad = _a.onStylesheetLoad, stylesheetLoadTimeout = _a.stylesheetLoadTimeout, _m = _a.keepIframeSrcFn, keepIframeSrcFn = _m === void 0 ? function () { return false; } : _m;
var maskInputOptions = maskAllInputs === true
? {
color: true,
date: true,
'datetime-local': true,
email: true,
month: true,
number: true,
range: true,
search: true,
tel: true,
text: true,
time: true,
url: true,
week: true,
textarea: true,
select: true,
password: true
}
: maskAllInputs === false
? {
password: true
}
: maskAllInputs;
var slimDOMOptions = slimDOM === true || slimDOM === 'all'
?
{
script: true,
comment: true,
headFavicon: true,
headWhitespace: true,
headMetaDescKeywords: slimDOM === 'all',
headMetaSocial: true,
headMetaRobots: true,
headMetaHttpEquiv: true,
headMetaAuthorship: true,
headMetaVerification: true
}
: slimDOM === false
? {}
: slimDOM;
return serializeNodeWithId(n, {
doc: n,
mirror: mirror,
blockClass: blockClass,
blockSelector: blockSelector,
maskTextClass: maskTextClass,
maskTextSelector: maskTextSelector,
skipChild: false,
inlineStylesheet: inlineStylesheet,
maskInputOptions: maskInputOptions,
maskTextFn: maskTextFn,
maskInputFn: maskInputFn,
slimDOMOptions: slimDOMOptions,
dataURLOptions: dataURLOptions,
inlineImages: inlineImages,
recordCanvas: recordCanvas,
preserveWhiteSpace: preserveWhiteSpace,
onSerialize: onSerialize,
onIframeLoad: onIframeLoad,
iframeLoadTimeout: iframeLoadTimeout,
onStylesheetLoad: onStylesheetLoad,
stylesheetLoadTimeout: stylesheetLoadTimeout,
keepIframeSrcFn: keepIframeSrcFn,
newlyAddedElement: false
});
}
function on(type, fn, target = document) {
const options = { capture: true, passive: true };
target.addEventListener(type, fn, options);
return () => target.removeEventListener(type, fn, options);
}
const DEPARTED_MIRROR_ACCESS_WARNING = 'Please stop import mirror directly. Instead of that,' +
'\r\n' +
'now you can use replayer.getMirror() to access the mirror instance of a replayer,' +
'\r\n' +
'or you can use record.mirror to access the mirror instance during recording.';
let _mirror = {
map: {},
getId() {
console.error(DEPARTED_MIRROR_ACCESS_WARNING);
return -1;
},
getNode() {
console.error(DEPARTED_MIRROR_ACCESS_WARNING);
return null;
},
removeNodeFromMap() {
console.error(DEPARTED_MIRROR_ACCESS_WARNING);
},
has() {
console.error(DEPARTED_MIRROR_ACCESS_WARNING);
return false;
},
reset() {
console.error(DEPARTED_MIRROR_ACCESS_WARNING);
},
};
if (typeof window !== 'undefined' && window.Proxy && window.Reflect) {
_mirror = new Proxy(_mirror, {
get(target, prop, receiver) {
if (prop === 'map') {
console.error(DEPARTED_MIRROR_ACCESS_WARNING);
}
return Reflect.get(target, prop, receiver);
},
});
}
function throttle(func, wait, options = {}) {
let timeout = null;
let previous = 0;
return function (...args) {
const now = Date.now();
if (!previous && options.leading === false) {
previous = now;
}
const remaining = wait - (now - previous);
const context = this;
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
func.apply(context, args);
}
else if (!timeout && options.trailing !== false) {
timeout = setTimeout(() => {
previous = options.leading === false ? 0 : Date.now();
timeout = null;
func.apply(context, args);
}, remaining);
}
};
}
function hookSetter(target, key, d, isRevoked, win = window) {
const original = win.Object.getOwnPropertyDescriptor(target, key);
win.Object.defineProperty(target, key, isRevoked
? d
: {
set(value) {
setTimeout(() => {
d.set.call(this, value);
}, 0);
if (original && original.set) {
original.set.call(this, value);
}
},
});
return () => hookSetter(target, key, original || {}, true);
}
function patch(source, name, replacement) {
try {
if (!(name in source)) {
return () => {
};
}
const original = source[name];
const wrapped = replacement(original);
if (typeof wrapped === 'function') {
wrapped.prototype = wrapped.prototype || {};
Object.defineProperties(wrapped, {
__rrweb_original__: {
enumerable: false,
value: original,
},
});
}
source[name] = wrapped;
return () => {
source[name] = original;
};
}
catch (_a) {
return () => {
};
}
}
function getWindowHeight() {
return (window.innerHeight ||
(document.documentElement && document.documentElement.clientHeight) ||
(document.body && document.body.clientHeight));
}
function getWindowWidth() {
return (window.innerWidth ||
(document.documentElement && document.documentElement.clientWidth) ||
(document.body && document.body.clientWidth));
}
function isBlocked(node, blockClass, blockSelector, checkAncestors) {
if (!node) {
return false;
}
const el = node.nodeType === node.ELEMENT_NODE
? node
: node.parentElement;
if (!el)
return false;
if (typeof blockClass === 'string') {
if (el.classList.contains(blockClass))
return true;
if (checkAncestors && el.closest('.' + blockClass) !== null)
return true;
}
else {
if (classMatchesRegex(el, blockClass, checkAncestors))
return true;
}
if (blockSelector) {
if (node.matches(blockSelector))
return true;
if (checkAncestors && el.closest(blockSelector) !== null)
return true;
}
return false;
}
function isSerialized(n, mirror) {
return mirror.getId(n) !== -1;
}
function isIgnored(n, mirror) {
return mirror.getId(n) === IGNORED_NODE;
}
function isAncestorRemoved(target, mirror) {
if (isShadowRoot(target)) {
return false;
}
const id = mirror.getId(target);
if (!mirror.has(id)) {
return true;
}
if (target.parentNode &&
target.parentNode.nodeType === target.DOCUMENT_NODE) {
return false;
}
if (!target.parentNode) {
return true;
}
return isAncestorRemoved(target.parentNode, mirror);
}
function isTouchEvent(event) {
return Boolean(event.changedTouches);
}
function polyfill(win = window) {
if ('NodeList' in win && !win.NodeList.prototype.forEach) {
win.NodeList.prototype.forEach = Array.prototype
.forEach;
}
if ('DOMTokenList' in win && !win.DOMTokenList.prototype.forEach) {
win.DOMTokenList.prototype.forEach = Array.prototype
.forEach;
}
if (!Node.prototype.contains) {
Node.prototype.contains = (...args) => {
let node = args[0];
if (!(0 in args)) {
throw new TypeError('1 argument is required');
}
do {
if (this === node) {
return true;
}
} while ((node = node && node.parentNode));
return false;
};
}
}
function isSerializedIframe(n, mirror) {
return Boolean(n.nodeName === 'IFRAME' && mirror.getMeta(n));
}
function isSerializedStylesheet(n, mirror) {
return Boolean(n.nodeName === 'LINK' &&
n.nodeType === n.ELEMENT_NODE &&
n.getAttribute &&
n.getAttribute('rel') === 'stylesheet' &&
mirror.getMeta(n));
}
function hasShadowRoot(n) {
return Boolean(n === null || n === void 0 ? void 0 : n.shadowRoot);
}
class StyleSheetMirror {
constructor() {
this.id = 1;
this.styleIDMap = new WeakMap();
this.idStyleMap = new Map();
}
getId(stylesheet) {
var _a;
return (_a = this.styleIDMap.get(stylesheet)) !== null && _a !== void 0 ? _a : -1;
}
has(stylesheet) {
return this.styleIDMap.has(stylesheet);
}
add(stylesheet, id) {
if (this.has(stylesheet))
return this.getId(stylesheet);
let newId;
if (id === undefined) {
newId = this.id++;
}
else
newId = id;
this.styleIDMap.set(stylesheet, newId);
this.idStyleMap.set(newId, stylesheet);
return newId;
}
getStyle(id) {
return this.idStyleMap.get(id) || null;
}
reset() {
this.styleIDMap = new WeakMap();
this.idStyleMap = new Map();
this.id = 1;
}
generateId() {
return this.id++;
}
}
var EventType = /* @__PURE__ */ ((EventType2) => {
EventType2[EventType2["DomContentLoaded"] = 0] = "DomContentLoaded";
EventType2[EventType2["Load"] = 1] = "Load";
EventType2[EventType2["FullSnapshot"] = 2] = "FullSnapshot";
EventType2[EventType2["IncrementalSnapshot"] = 3] = "IncrementalSnapshot";
EventType2[EventType2["Meta"] = 4] = "Meta";
EventType2[EventType2["Custom"] = 5] = "Custom";
EventType2[EventType2["Plugin"] = 6] = "Plugin";
return EventType2;
})(EventType || {});
var IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {
IncrementalSource2[IncrementalSource2["Mutation"] = 0] = "Mutation";
IncrementalSource2[IncrementalSource2["MouseMove"] = 1] = "MouseMove";
IncrementalSource2[IncrementalSource2["MouseInteraction"] = 2] = "MouseInteraction";
IncrementalSource2[IncrementalSource2["Scroll"] = 3] = "Scroll";
IncrementalSource2[IncrementalSource2["ViewportResize"] = 4] = "ViewportResize";
IncrementalSource2[IncrementalSource2["Input"] = 5] = "Input";
IncrementalSource2[IncrementalSource2["TouchMove"] = 6] = "TouchMove";
IncrementalSource2[IncrementalSource2["MediaInteraction"] = 7] = "MediaInteraction";
IncrementalSource2[IncrementalSource2["StyleSheetRule"] = 8] = "StyleSheetRule";
IncrementalSource2[IncrementalSource2["CanvasMutation"] = 9] = "CanvasMutation";
IncrementalSource2[IncrementalSource2["Font"] = 10] = "Font";
IncrementalSource2[IncrementalSource2["Log"] = 11] = "Log";
IncrementalSource2[IncrementalSource2["Drag"] = 12] = "Drag";
IncrementalSource2[IncrementalSource2["StyleDeclaration"] = 13] = "StyleDeclaration";
IncrementalSource2[IncrementalSource2["Selection"] = 14] = "Selection";
IncrementalSource2[IncrementalSource2["AdoptedStyleSheet"] = 15] = "AdoptedStyleSheet";
return IncrementalSource2;
})(IncrementalSource || {});
var MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {
MouseInteractions2[MouseInteractions2["MouseUp"] = 0] = "MouseUp";
MouseInteractions2[MouseInteractions2["MouseDown"] = 1] = "MouseDown";
MouseInteractions2[MouseInteractions2["Click"] = 2] = "Click";
MouseInter