rrweb
Version:
record and replay the web
1,359 lines (1,345 loc) • 79.7 kB
JavaScript
'use strict';
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __values(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
}
function __spread() {
for (var ar = [], i = 0; i < arguments.length; i++)
ar = ar.concat(__read(arguments[i]));
return ar;
}
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 = {}));
var _id = 1;
var tagNameRegex = RegExp('[^a-z1-6-_]');
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 getCssRulesString(s) {
try {
var rules = s.rules || s.cssRules;
return rules ? Array.from(rules).map(getCssRuleString).join('') : null;
}
catch (error) {
return null;
}
}
function getCssRuleString(rule) {
return isCSSImportRule(rule)
? getCssRulesString(rule.styleSheet) || ''
: rule.cssText;
}
function isCSSImportRule(rule) {
return 'styleSheet' in rule;
}
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 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(" + maybeQuote + filePath + maybeQuote + ")";
}
if (DATA_URI.test(filePath)) {
return "url(" + maybeQuote + filePath + maybeQuote + ")";
}
if (filePath[0] === '/') {
return "url(" + maybeQuote + (extractOrigin(href) + filePath) + 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(" + maybeQuote + stack.join('/') + maybeQuote + ")";
});
}
function getAbsoluteSrcsetString(doc, attributeValue) {
if (attributeValue.trim() === '') {
return attributeValue;
}
var srcsetValues = attributeValue.split(',');
var resultingSrcsetString = srcsetValues
.map(function (srcItem) {
var trimmedSrcItem = srcItem.trimLeft().trimRight();
var urlAndSize = trimmedSrcItem.split(' ');
if (urlAndSize.length === 2) {
var absUrl = absoluteToDoc(doc, urlAndSize[0]);
return absUrl + " " + urlAndSize[1];
}
else if (urlAndSize.length === 1) {
var absUrl = absoluteToDoc(doc, urlAndSize[0]);
return "" + absUrl;
}
return '';
})
.join(', ');
return resultingSrcsetString;
}
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 el.tagName === 'svg' || el instanceof SVGElement;
}
function transformAttribute(doc, name, value) {
if (name === 'src' || ((name === 'href' || name === 'xlink:href') && value)) {
return absoluteToDoc(doc, value);
}
else if (name === 'srcset' && value) {
return getAbsoluteSrcsetString(doc, value);
}
else if (name === 'style' && value) {
return absoluteToStylesheet(value, location.href);
}
else {
return value;
}
}
function _isBlockedElement(element, blockClass, blockSelector) {
if (typeof blockClass === 'string') {
if (element.classList.contains(blockClass)) {
return true;
}
}
else {
element.classList.forEach(function (className) {
if (blockClass.test(className)) {
return true;
}
});
}
if (blockSelector) {
return element.matches(blockSelector);
}
return false;
}
function serializeNode(n, options) {
var doc = options.doc, blockClass = options.blockClass, blockSelector = options.blockSelector, inlineStylesheet = options.inlineStylesheet, _a = options.maskInputOptions, maskInputOptions = _a === void 0 ? {} : _a, recordCanvas = options.recordCanvas;
switch (n.nodeType) {
case n.DOCUMENT_NODE:
return {
type: NodeType.Document,
childNodes: [],
};
case n.DOCUMENT_TYPE_NODE:
return {
type: NodeType.DocumentType,
name: n.name,
publicId: n.publicId,
systemId: n.systemId,
};
case n.ELEMENT_NODE:
var needBlock = _isBlockedElement(n, blockClass, blockSelector);
var tagName = getValidTagName(n);
var attributes_1 = {};
for (var _i = 0, _b = Array.from(n.attributes); _i < _b.length; _i++) {
var _c = _b[_i], name = _c.name, value = _c.value;
attributes_1[name] = transformAttribute(doc, name, value);
}
if (tagName === 'link' && inlineStylesheet) {
var stylesheet = Array.from(doc.styleSheets).find(function (s) {
return s.href === n.href;
});
var cssText = getCssRulesString(stylesheet);
if (cssText) {
delete attributes_1.rel;
delete attributes_1.href;
attributes_1._cssText = absoluteToStylesheet(cssText, stylesheet.href);
}
}
if (tagName === 'style' &&
n.sheet &&
!(n.innerText ||
n.textContent ||
'').trim().length) {
var cssText = getCssRulesString(n.sheet);
if (cssText) {
attributes_1._cssText = absoluteToStylesheet(cssText, location.href);
}
}
if (tagName === 'input' ||
tagName === 'textarea' ||
tagName === 'select') {
var value = n.value;
if (attributes_1.type !== 'radio' &&
attributes_1.type !== 'checkbox' &&
attributes_1.type !== 'submit' &&
attributes_1.type !== 'button' &&
value) {
attributes_1.value =
maskInputOptions[attributes_1.type] ||
maskInputOptions[tagName]
? '*'.repeat(value.length)
: value;
}
else if (n.checked) {
attributes_1.checked = n.checked;
}
}
if (tagName === 'option') {
var selectValue = n.parentElement;
if (attributes_1.value === selectValue.value) {
attributes_1.selected = n.selected;
}
}
if (tagName === 'canvas' && recordCanvas) {
attributes_1.rr_dataURL = n.toDataURL();
}
if (tagName === 'audio' || tagName === 'video') {
attributes_1.rr_mediaState = n.paused
? 'paused'
: 'played';
}
if (n.scrollLeft) {
attributes_1.rr_scrollLeft = n.scrollLeft;
}
if (n.scrollTop) {
attributes_1.rr_scrollTop = n.scrollTop;
}
if (needBlock) {
var _d = n.getBoundingClientRect(), width = _d.width, height = _d.height;
attributes_1 = {
class: attributes_1.class,
rr_width: width + "px",
rr_height: height + "px",
};
}
return {
type: NodeType.Element,
tagName: tagName,
attributes: attributes_1,
childNodes: [],
isSVG: isSVGElement(n) || undefined,
needBlock: needBlock,
};
case n.TEXT_NODE:
var parentTagName = n.parentNode && n.parentNode.tagName;
var textContent = n.textContent;
var isStyle = parentTagName === 'STYLE' ? true : undefined;
if (isStyle && textContent) {
textContent = absoluteToStylesheet(textContent, location.href);
}
if (parentTagName === 'SCRIPT') {
textContent = 'SCRIPT_PLACEHOLDER';
}
return {
type: NodeType.Text,
textContent: textContent || '',
isStyle: isStyle,
};
case n.CDATA_SECTION_NODE:
return {
type: NodeType.CDATA,
textContent: '',
};
case n.COMMENT_NODE:
return {
type: NodeType.Comment,
textContent: n.textContent || '',
};
default:
return false;
}
}
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'))) {
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, map = options.map, blockClass = options.blockClass, blockSelector = options.blockSelector, _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, slimDOMOptions = options.slimDOMOptions, _d = options.recordCanvas, recordCanvas = _d === void 0 ? false : _d;
var _e = options.preserveWhiteSpace, preserveWhiteSpace = _e === void 0 ? true : _e;
var _serializedNode = serializeNode(n, {
doc: doc,
blockClass: blockClass,
blockSelector: blockSelector,
inlineStylesheet: inlineStylesheet,
maskInputOptions: maskInputOptions,
recordCanvas: recordCanvas,
});
if (!_serializedNode) {
console.warn(n, 'not serialized');
return null;
}
var id;
if ('__sn' in n) {
id = n.__sn.id;
}
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 });
n.__sn = serializedNode;
if (id === IGNORED_NODE) {
return null;
}
map[id] = n;
var recordChild = !skipChild;
if (serializedNode.type === NodeType.Element) {
recordChild = recordChild && !serializedNode.needBlock;
delete serializedNode.needBlock;
}
if ((serializedNode.type === NodeType.Document ||
serializedNode.type === NodeType.Element) &&
recordChild) {
if (slimDOMOptions.headWhitespace &&
_serializedNode.type === NodeType.Element &&
_serializedNode.tagName === 'head') {
preserveWhiteSpace = false;
}
for (var _i = 0, _f = Array.from(n.childNodes); _i < _f.length; _i++) {
var childN = _f[_i];
var serializedChildNode = serializeNodeWithId(childN, {
doc: doc,
map: map,
blockClass: blockClass,
blockSelector: blockSelector,
skipChild: skipChild,
inlineStylesheet: inlineStylesheet,
maskInputOptions: maskInputOptions,
slimDOMOptions: slimDOMOptions,
recordCanvas: recordCanvas,
preserveWhiteSpace: preserveWhiteSpace,
});
if (serializedChildNode) {
serializedNode.childNodes.push(serializedChildNode);
}
}
}
return serializedNode;
}
function snapshot(n, options) {
var _a = options || {}, _b = _a.blockClass, blockClass = _b === void 0 ? 'rr-block' : _b, _c = _a.inlineStylesheet, inlineStylesheet = _c === void 0 ? true : _c, _d = _a.recordCanvas, recordCanvas = _d === void 0 ? false : _d, _e = _a.blockSelector, blockSelector = _e === void 0 ? null : _e, _f = _a.maskAllInputs, maskAllInputs = _f === void 0 ? false : _f, _g = _a.slimDOM, slimDOM = _g === void 0 ? false : _g;
var idNodeMap = {};
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,
}
: maskAllInputs === false
? {}
: 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,
map: idNodeMap,
blockClass: blockClass,
blockSelector: blockSelector,
skipChild: false,
inlineStylesheet: inlineStylesheet,
maskInputOptions: maskInputOptions,
slimDOMOptions: slimDOMOptions,
recordCanvas: recordCanvas,
}),
idNodeMap,
];
}
var EventType;
(function (EventType) {
EventType[EventType["DomContentLoaded"] = 0] = "DomContentLoaded";
EventType[EventType["Load"] = 1] = "Load";
EventType[EventType["FullSnapshot"] = 2] = "FullSnapshot";
EventType[EventType["IncrementalSnapshot"] = 3] = "IncrementalSnapshot";
EventType[EventType["Meta"] = 4] = "Meta";
EventType[EventType["Custom"] = 5] = "Custom";
})(EventType || (EventType = {}));
var IncrementalSource;
(function (IncrementalSource) {
IncrementalSource[IncrementalSource["Mutation"] = 0] = "Mutation";
IncrementalSource[IncrementalSource["MouseMove"] = 1] = "MouseMove";
IncrementalSource[IncrementalSource["MouseInteraction"] = 2] = "MouseInteraction";
IncrementalSource[IncrementalSource["Scroll"] = 3] = "Scroll";
IncrementalSource[IncrementalSource["ViewportResize"] = 4] = "ViewportResize";
IncrementalSource[IncrementalSource["Input"] = 5] = "Input";
IncrementalSource[IncrementalSource["TouchMove"] = 6] = "TouchMove";
IncrementalSource[IncrementalSource["MediaInteraction"] = 7] = "MediaInteraction";
IncrementalSource[IncrementalSource["StyleSheetRule"] = 8] = "StyleSheetRule";
IncrementalSource[IncrementalSource["CanvasMutation"] = 9] = "CanvasMutation";
IncrementalSource[IncrementalSource["Font"] = 10] = "Font";
IncrementalSource[IncrementalSource["Log"] = 11] = "Log";
})(IncrementalSource || (IncrementalSource = {}));
var MouseInteractions;
(function (MouseInteractions) {
MouseInteractions[MouseInteractions["MouseUp"] = 0] = "MouseUp";
MouseInteractions[MouseInteractions["MouseDown"] = 1] = "MouseDown";
MouseInteractions[MouseInteractions["Click"] = 2] = "Click";
MouseInteractions[MouseInteractions["ContextMenu"] = 3] = "ContextMenu";
MouseInteractions[MouseInteractions["DblClick"] = 4] = "DblClick";
MouseInteractions[MouseInteractions["Focus"] = 5] = "Focus";
MouseInteractions[MouseInteractions["Blur"] = 6] = "Blur";
MouseInteractions[MouseInteractions["TouchStart"] = 7] = "TouchStart";
MouseInteractions[MouseInteractions["TouchMove_Departed"] = 8] = "TouchMove_Departed";
MouseInteractions[MouseInteractions["TouchEnd"] = 9] = "TouchEnd";
})(MouseInteractions || (MouseInteractions = {}));
var MediaInteractions;
(function (MediaInteractions) {
MediaInteractions[MediaInteractions["Play"] = 0] = "Play";
MediaInteractions[MediaInteractions["Pause"] = 1] = "Pause";
})(MediaInteractions || (MediaInteractions = {}));
var ReplayerEvents;
(function (ReplayerEvents) {
ReplayerEvents["Start"] = "start";
ReplayerEvents["Pause"] = "pause";
ReplayerEvents["Resume"] = "resume";
ReplayerEvents["Resize"] = "resize";
ReplayerEvents["Finish"] = "finish";
ReplayerEvents["FullsnapshotRebuilded"] = "fullsnapshot-rebuilded";
ReplayerEvents["LoadStylesheetStart"] = "load-stylesheet-start";
ReplayerEvents["LoadStylesheetEnd"] = "load-stylesheet-end";
ReplayerEvents["SkipStart"] = "skip-start";
ReplayerEvents["SkipEnd"] = "skip-end";
ReplayerEvents["MouseInteraction"] = "mouse-interaction";
ReplayerEvents["EventCast"] = "event-cast";
ReplayerEvents["CustomEvent"] = "custom-event";
ReplayerEvents["Flush"] = "flush";
ReplayerEvents["StateChange"] = "state-change";
})(ReplayerEvents || (ReplayerEvents = {}));
function on(type, fn, target) {
if (target === void 0) { target = document; }
var options = { capture: true, passive: true };
target.addEventListener(type, fn, options);
return function () { return target.removeEventListener(type, fn, options); };
}
var mirror = {
map: {},
getId: function (n) {
if (!n.__sn) {
return -1;
}
return n.__sn.id;
},
getNode: function (id) {
return mirror.map[id] || null;
},
removeNodeFromMap: function (n) {
var id = n.__sn && n.__sn.id;
delete mirror.map[id];
if (n.childNodes) {
n.childNodes.forEach(function (child) {
return mirror.removeNodeFromMap(child);
});
}
},
has: function (id) {
return mirror.map.hasOwnProperty(id);
},
};
function throttle(func, wait, options) {
if (options === void 0) { options = {}; }
var timeout = null;
var previous = 0;
return function (arg) {
var now = Date.now();
if (!previous && options.leading === false) {
previous = now;
}
var remaining = wait - (now - previous);
var context = this;
var args = arguments;
if (remaining <= 0 || remaining > wait) {
if (timeout) {
window.clearTimeout(timeout);
timeout = null;
}
previous = now;
func.apply(context, args);
}
else if (!timeout && options.trailing !== false) {
timeout = window.setTimeout(function () {
previous = options.leading === false ? 0 : Date.now();
timeout = null;
func.apply(context, args);
}, remaining);
}
};
}
function hookSetter(target, key, d, isRevoked, win) {
if (win === void 0) { win = window; }
var original = win.Object.getOwnPropertyDescriptor(target, key);
win.Object.defineProperty(target, key, isRevoked
? d
: {
set: function (value) {
var _this = this;
setTimeout(function () {
d.set.call(_this, value);
}, 0);
if (original && original.set) {
original.set.call(this, value);
}
},
});
return function () { return hookSetter(target, key, original || {}, true); };
}
function patch(source, name, replacement) {
try {
if (!(name in source)) {
return function () { };
}
var original_1 = source[name];
var wrapped = replacement(original_1);
if (typeof wrapped === 'function') {
wrapped.prototype = wrapped.prototype || {};
Object.defineProperties(wrapped, {
__rrweb_original__: {
enumerable: false,
value: original_1,
},
});
}
source[name] = wrapped;
return function () {
source[name] = original_1;
};
}
catch (_a) {
return function () { };
}
}
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) {
if (!node) {
return false;
}
if (node.nodeType === node.ELEMENT_NODE) {
var needBlock_1 = false;
if (typeof blockClass === 'string') {
needBlock_1 = node.classList.contains(blockClass);
}
else {
node.classList.forEach(function (className) {
if (blockClass.test(className)) {
needBlock_1 = true;
}
});
}
return needBlock_1 || isBlocked(node.parentNode, blockClass);
}
if (node.nodeType === node.TEXT_NODE) {
return isBlocked(node.parentNode, blockClass);
}
return isBlocked(node.parentNode, blockClass);
}
function isIgnored(n) {
if ('__sn' in n) {
return n.__sn.id === IGNORED_NODE;
}
return false;
}
function isAncestorRemoved(target) {
var 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);
}
function isTouchEvent(event) {
return Boolean(event.changedTouches);
}
function polyfill(win) {
if (win === void 0) { 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;
}
}
function isNodeInLinkedList(n) {
return '__ln' in n;
}
var DoubleLinkedList = (function () {
function DoubleLinkedList() {
this.length = 0;
this.head = null;
}
DoubleLinkedList.prototype.get = function (position) {
if (position >= this.length) {
throw new Error('Position outside of list range');
}
var current = this.head;
for (var index = 0; index < position; index++) {
current = (current === null || current === void 0 ? void 0 : current.next) || null;
}
return current;
};
DoubleLinkedList.prototype.addNode = function (n) {
var node = {
value: n,
previous: null,
next: null,
};
n.__ln = node;
if (n.previousSibling && isNodeInLinkedList(n.previousSibling)) {
var current = n.previousSibling.__ln.next;
node.next = current;
node.previous = n.previousSibling.__ln;
n.previousSibling.__ln.next = node;
if (current) {
current.previous = node;
}
}
else if (n.nextSibling && isNodeInLinkedList(n.nextSibling)) {
var current = n.nextSibling.__ln.previous;
node.previous = current;
node.next = n.nextSibling.__ln;
n.nextSibling.__ln.previous = node;
if (current) {
current.next = node;
}
}
else {
if (this.head) {
this.head.previous = node;
}
node.next = this.head;
this.head = node;
}
this.length++;
};
DoubleLinkedList.prototype.removeNode = function (n) {
var current = n.__ln;
if (!this.head) {
return;
}
if (!current.previous) {
this.head = current.next;
if (this.head) {
this.head.previous = null;
}
}
else {
current.previous.next = current.next;
if (current.next) {
current.next.previous = current.previous;
}
}
if (n.__ln) {
delete n.__ln;
}
this.length--;
};
return DoubleLinkedList;
}());
var moveKey = function (id, parentId) { return id + "@" + parentId; };
function isINode(n) {
return '__sn' in n;
}
var MutationBuffer = (function () {
function MutationBuffer() {
var _this = this;
this.frozen = false;
this.texts = [];
this.attributes = [];
this.removes = [];
this.mapRemoves = [];
this.movedMap = {};
this.addedSet = new Set();
this.movedSet = new Set();
this.droppedSet = new Set();
this.processMutations = function (mutations) {
mutations.forEach(_this.processMutation);
if (!_this.frozen) {
_this.emit();
}
};
this.emit = function () {
var e_1, _a, e_2, _b;
var adds = [];
var addList = new DoubleLinkedList();
var getNextId = function (n) {
var ns = n;
var nextId = IGNORED_NODE;
while (nextId === IGNORED_NODE) {
ns = ns && ns.nextSibling;
nextId = ns && mirror.getId(ns);
}
if (nextId === -1 && isBlocked(n.nextSibling, _this.blockClass)) {
nextId = null;
}
return nextId;
};
var pushAdd = function (n) {
if (!n.parentNode || !document.contains(n)) {
return;
}
var parentId = mirror.getId(n.parentNode);
var nextId = getNextId(n);
if (parentId === -1 || nextId === -1) {
return addList.addNode(n);
}
var sn = serializeNodeWithId(n, {
doc: document,
map: mirror.map,
blockClass: _this.blockClass,
blockSelector: _this.blockSelector,
skipChild: true,
inlineStylesheet: _this.inlineStylesheet,
maskInputOptions: _this.maskInputOptions,
slimDOMOptions: _this.slimDOMOptions,
recordCanvas: _this.recordCanvas,
});
if (sn) {
adds.push({
parentId: parentId,
nextId: nextId,
node: sn,
});
}
};
while (_this.mapRemoves.length) {
mirror.removeNodeFromMap(_this.mapRemoves.shift());
}
try {
for (var _c = __values(_this.movedSet), _d = _c.next(); !_d.done; _d = _c.next()) {
var n = _d.value;
if (isParentRemoved(_this.removes, n) &&
!_this.movedSet.has(n.parentNode)) {
continue;
}
pushAdd(n);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
}
finally { if (e_1) throw e_1.error; }
}
try {
for (var _e = __values(_this.addedSet), _f = _e.next(); !_f.done; _f = _e.next()) {
var n = _f.value;
if (!isAncestorInSet(_this.droppedSet, n) &&
!isParentRemoved(_this.removes, n)) {
pushAdd(n);
}
else if (isAncestorInSet(_this.movedSet, n)) {
pushAdd(n);
}
else {
_this.droppedSet.add(n);
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
}
finally { if (e_2) throw e_2.error; }
}
var candidate = null;
while (addList.length) {
var node = null;
if (candidate) {
var parentId = mirror.getId(candidate.value.parentNode);
var nextId = getNextId(candidate.value);
if (parentId !== -1 && nextId !== -1) {
node = candidate;
}
}
if (!node) {
for (var index = addList.length - 1; index >= 0; index--) {
var _node = addList.get(index);
var parentId = mirror.getId(_node.value.parentNode);
var nextId = getNextId(_node.value);
if (parentId !== -1 && nextId !== -1) {
node = _node;
break;
}
}
}
if (!node) {
while (addList.head) {
addList.removeNode(addList.head.value);
}
break;
}
candidate = node.previous;
addList.removeNode(node.value);
pushAdd(node.value);
}
var payload = {
texts: _this.texts
.map(function (text) { return ({
id: mirror.getId(text.node),
value: text.value,
}); })
.filter(function (text) { return mirror.has(text.id); }),
attributes: _this.attributes
.map(function (attribute) { return ({
id: mirror.getId(attribute.node),
attributes: attribute.attributes,
}); })
.filter(function (attribute) { return mirror.has(attribute.id); }),
removes: _this.removes,
adds: adds,
};
if (!payload.texts.length &&
!payload.attributes.length &&
!payload.removes.length &&
!payload.adds.length) {
return;
}
_this.texts = [];
_this.attributes = [];
_this.removes = [];
_this.addedSet = new Set();
_this.movedSet = new Set();
_this.droppedSet = new Set();
_this.movedMap = {};
_this.emissionCallback(payload);
};
this.processMutation = function (m) {
if (isIgnored(m.target)) {
return;
}
switch (m.type) {
case 'characterData': {
var value = m.target.textContent;
if (!isBlocked(m.target, _this.blockClass) && value !== m.oldValue) {
_this.texts.push({
value: value,
node: m.target,
});
}
break;
}
case 'attributes': {
var value = m.target.getAttribute(m.attributeName);
if (isBlocked(m.target, _this.blockClass) || value === m.oldValue) {
return;
}
var item = _this.attributes.find(function (a) { return a.node === m.target; });
if (!item) {
item = {
node: m.target,
attributes: {},
};
_this.attributes.push(item);
}
item.attributes[m.attributeName] = transformAttribute(document, m.attributeName, value);
break;
}
case 'childList': {
m.addedNodes.forEach(function (n) { return _this.genAdds(n, m.target); });
m.removedNodes.forEach(function (n) {
var nodeId = mirror.getId(n);
var parentId = mirror.getId(m.target);
if (isBlocked(n, _this.blockClass) ||
isBlocked(m.target, _this.blockClass) ||
isIgnored(n)) {
return;
}
if (_this.addedSet.has(n)) {
deepDelete(_this.addedSet, n);
_this.droppedSet.add(n);
}
else if (_this.addedSet.has(m.target) && nodeId === -1) ;
else if (isAncestorRemoved(m.target)) ;
else if (_this.movedSet.has(n) &&
_this.movedMap[moveKey(nodeId, parentId)]) {
deepDelete(_this.movedSet, n);
}
else {
_this.removes.push({
parentId: parentId,
id: nodeId,
});
}
_this.mapRemoves.push(n);
});
break;
}
}
};
this.genAdds = function (n, target) {
if (isBlocked(n, _this.blockClass)) {
return;
}
if (target && isBlocked(target, _this.blockClass)) {
return;
}
if (isINode(n)) {
if (isIgnored(n)) {
return;
}
_this.movedSet.add(n);
var targetId = null;
if (target && isINode(target)) {
targetId = target.__sn.id;
}
if (targetId) {
_this.movedMap[moveKey(n.__sn.id, targetId)] = true;
}
}
else {
_this.addedSet.add(n);
_this.droppedSet.delete(n);
}
n.childNodes.forEach(function (childN) { return _this.genAdds(childN); });
};
}
MutationBuffer.prototype.init = function (cb, blockClass, blockSelector, inlineStylesheet, maskInputOptions, recordCanvas, slimDOMOptions) {
this.blockClass = blockClass;
this.blockSelector = blockSelector;
this.inlineStylesheet = inlineStylesheet;
this.maskInputOptions = maskInputOptions;
this.recordCanvas = recordCanvas;
this.slimDOMOptions = slimDOMOptions;
this.emissionCallback = cb;
};
MutationBuffer.prototype.freeze = function () {
this.frozen = true;
};
MutationBuffer.prototype.unfreeze = function () {
this.frozen = false;
};
MutationBuffer.prototype.isFrozen = function () {
return this.frozen;
};
return MutationBuffer;
}());
function deepDelete(addsSet, n) {
addsSet.delete(n);
n.childNodes.forEach(function (childN) { return deepDelete(addsSet, childN); });
}
function isParentRemoved(removes, n) {
var parentNode = n.parentNode;
if (!parentNode) {
return false;
}
var parentId = mirror.getId(parentNode);
if (removes.some(function (r) { return r.id === parentId; })) {
return true;
}
return isParentRemoved(removes, parentNode);
}
function isAncestorInSet(set, n) {
var parentNode = n.parentNode;
if (!parentNode) {
return false;
}
if (set.has(parentNode)) {
return true;
}
return isAncestorInSet(set, parentNode);
}
function pathToSelector(node) {
if (!node || !node.outerHTML) {
return '';
}
var path = '';
while (node.parentElement) {
var name = node.localName;
if (!name)
break;
name = name.toLowerCase();
var parent = node.parentElement;
var domSiblings = [];
if (parent.children && parent.children.length > 0) {
for (var i = 0; i < parent.children.length; i++) {
var sibling = parent.children[i];
if (sibling.localName && sibling.localName.toLowerCase) {
if (sibling.localName.toLowerCase() === name) {
domSiblings.push(sibling);
}
}
}
}
if (domSiblings.length > 1) {
name += ':eq(' + domSiblings.indexOf(node) + ')';
}
path = name + (path ? '>' + path : '');
node = parent;
}
return path;
}
function stringify(obj, stringifyOptions) {
var options = {
numOfKeysLimit: 50,
};
Object.assign(options, stringifyOptions);
var stack = [], keys = [];
return JSON.stringify(obj, function (key, value) {
if (stack.length > 0) {
var thisPos = stack.indexOf(this);
~thisPos ? stack.splice(thisPos + 1) : stack.push(this);
~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);
if (~stack.indexOf(value)) {
if (stack[0] === value)
value = '[Circular ~]';
else
value =
'[Circular ~.' +
keys.slice(0, stack.indexOf(value)).join('.') +
']';
}
}
else
stack.push(value);
if (value === null || value === undefined)
return value;
if (shouldToString(value)) {
return toString(value);
}
if (value instanceof Event) {
var eventResult = {};
for (var key_1 in value) {
var eventValue = value[key_1];
if (Array.isArray(eventValue))
eventResult[key_1] = pathToSelector(eventValue.length ? eventValue[0] : null);
else
eventResult[key_1] = eventValue;
}
return eventResult;
}
else if (value instanceof Node) {
if (value instanceof HTMLElement)
return value ? value.outerHTML : '';
return value.nodeName;
}
return value;
});
function shouldToString(obj) {
if (typeof obj === 'object' &&
Object.keys(obj).length > options.numOfKeysLimit)
return true;
if (typeof obj === 'function')
return true;
return false;
}
function toString(obj) {
var str = obj.toString();
if (options.stringLengthLimit && str.length > options.stringLengthLimit) {
str = str.slice(0, options.stringLengthLimit) + "...";
}
return str;
}
}
var mutationBuffer = new MutationBuffer();
function initMutationObserver(cb, blockClass, blockSelector, inlineStylesheet, maskInputOptions, recordCanvas, slimDOMOptions) {
mutationBuffer.init(cb, blockClass, blockSelector, inlineStylesheet, maskInputOptions, recordCanvas, slimDOMOptions);
var observer = new MutationObserver(mutationBuffer.processMutations.bind(mutationBuffer));
observer.observe(document, {
attributes: true,
attributeOldValue: true,
characterData: true,
characterDataOldValue: true,
childList: true,
subtree: true,
});
return observer;
}
function initMoveObserver(cb, sampling) {
if (sampling.mousemove === false) {
return function () { };
}
var threshold = typeof sampling.mousemove === 'number' ? sampling.mousemove : 50;
var positions = [];
var timeBaseline;
var wrappedCb = throttle(function (isTouch) {
var totalOffset = Date.now() - timeBaseline;
cb(positions.map(function (p) {
p.timeOffset -= totalOffset;
return p;
}), isTouch ? IncrementalSource.TouchMove : IncrementalSource.MouseMove);
positions = [];
timeBaseline = null;
}, 500);
var updatePosition = throttle(function (evt) {
var target = evt.target;
var _a = isTouchEvent(evt)
? evt.changedTouches[0]
: evt, clientX = _a.clientX, clientY = _a.clientY;
if (!timeBaseline) {
timeBaseline = Date.now();
}
positions.push({
x: clientX,
y: clientY,
id: mirror.getId(target),
timeOffset: Date.now() - timeBaseline,
});
wrappedCb(isTouchEvent(evt));
}, threshold, {
trailing: false,
});
var handlers = [
on('mousemove', updatePosition),
on('touchmove', updatePosition),
];
return function () {
handlers.forEach(function (h) { return h(); });
};
}
function initMouseInteractionObserver(cb, blockClass, sampling) {
if (sampling.mouseInteraction === false) {
return function () { };
}
var disableMap = sampling.mouseInteraction === true ||
sampling.mouseInteraction === undefined
? {}
: sampling.mouseInteraction;
var handlers = [];
var getHandler = function (eventKey) {
return function (event) {
if (isBlocked(event.target, blockClass)) {
return;
}
var id = mirror.getId(event.target);
var _a = isTouchEvent(event)
? event.changedTouches[0]
: event, clientX = _a.clientX, clientY = _a.clientY;
cb({
type: MouseInteractions[eventKey],
id: id,
x: clientX,
y: clientY,
});
};
};
Object.keys(MouseInteractions)
.filter(function (key) {
return Number.isNaN(Number(key)) &&
!key.endsWith('_Departed') &&
disableMap[key] !== false;
})
.forEach(function (eventKey) {
var eventName = eventKey.toLowerCase();
var handler = getHandler(eventKey);
handlers.push(on(eventName, handler));
});
return function () {
handlers.forEach(function (h) { return h(); });
};
}
function initScrollObserver(cb, blockClass, sampling) {
var updatePosition = throttle(function (evt) {
if (!evt.target || isBlocked(evt.target, blockClass)) {
return;
}
var id = mirror.getId(evt.target);
if (evt.target === document) {
var scrollEl = (document.scrollingElement || document.documentElemen