rrweb
Version:
record and replay the web
1,236 lines (1,221 loc) • 55.3 kB
JavaScript
var rrwebRecord = (function () {
'use strict';
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
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 m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
}
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 symbolAndNumberRegex = RegExp('[^a-z1-6-]');
function genId() {
return _id++;
}
function getValidTagName(tagName) {
var processedTagName = tagName.toLowerCase().trim();
if (symbolAndNumberRegex.test(processedTagName)) {
return 'div';
}
return processedTagName;
}
function getCssRulesString(s) {
try {
var rules = s.rules || s.cssRules;
return rules
? Array.from(rules).reduce(function (prev, cur) { return prev + getCssRuleString(cur); }, '')
: 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:)([\w\/\+\-]+);(charset=[\w-]+|base64).*,(.*)/i;
function absoluteToStylesheet(cssText, href) {
return (cssText || '').replace(URL_IN_CSS_REF, function (origin, path1, path2, path3) {
var filePath = path1 || path2 || path3;
if (!filePath) {
return origin;
}
if (!RELATIVE_PATH.test(filePath)) {
return "url('" + filePath + "')";
}
if (DATA_URI.test(filePath)) {
return "url(" + filePath + ")";
}
if (filePath[0] === '/') {
return "url('" + (extractOrigin(href) + filePath) + "')";
}
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('" + stack.join('/') + "')";
});
}
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' && 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 serializeNode(n, doc, blockClass, inlineStylesheet, maskInputOptions) {
if (maskInputOptions === void 0) { maskInputOptions = {}; }
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_1 = false;
if (typeof blockClass === 'string') {
needBlock_1 = n.classList.contains(blockClass);
}
else {
n.classList.forEach(function (className) {
if (blockClass.test(className)) {
needBlock_1 = true;
}
});
}
var tagName = getValidTagName(n.tagName);
var attributes_1 = {};
for (var _i = 0, _a = Array.from(n.attributes); _i < _a.length; _i++) {
var _b = _a[_i], name = _b.name, value = _b.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') {
attributes_1.rr_dataURL = n.toDataURL();
}
if (tagName === 'audio' || tagName === 'video') {
attributes_1.rr_mediaState = n.paused
? 'paused'
: 'played';
}
if (needBlock_1) {
var _c = n.getBoundingClientRect(), width = _c.width, height = _c.height;
attributes_1.rr_width = width + "px";
attributes_1.rr_height = height + "px";
}
return {
type: NodeType.Element,
tagName: tagName,
attributes: attributes_1,
childNodes: [],
isSVG: isSVGElement(n) || undefined,
needBlock: needBlock_1
};
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 serializeNodeWithId(n, doc, map, blockClass, skipChild, inlineStylesheet, maskInputOptions) {
if (skipChild === void 0) { skipChild = false; }
if (inlineStylesheet === void 0) { inlineStylesheet = true; }
var _serializedNode = serializeNode(n, doc, blockClass, inlineStylesheet, maskInputOptions);
if (!_serializedNode) {
console.warn(n, 'not serialized');
return null;
}
var id;
if ('__sn' in n) {
id = n.__sn.id;
}
else {
id = genId();
}
var serializedNode = Object.assign(_serializedNode, { id: id });
n.__sn = serializedNode;
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) {
for (var _i = 0, _a = Array.from(n.childNodes); _i < _a.length; _i++) {
var childN = _a[_i];
var serializedChildNode = serializeNodeWithId(childN, doc, map, blockClass, skipChild, inlineStylesheet, maskInputOptions);
if (serializedChildNode) {
serializedNode.childNodes.push(serializedChildNode);
}
}
}
return serializedNode;
}
function snapshot(n, blockClass, inlineStylesheet, maskAllInputsOrOptions) {
if (blockClass === void 0) { blockClass = 'rr-block'; }
if (inlineStylesheet === void 0) { inlineStylesheet = true; }
var idNodeMap = {};
var maskInputOptions = maskAllInputsOrOptions === 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
}
: maskAllInputsOrOptions === false
? {}
: maskAllInputsOrOptions;
return [
serializeNodeWithId(n, n, idNodeMap, blockClass, false, inlineStylesheet, maskInputOptions),
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 = {}));
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 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 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() {
if ('NodeList' in window && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = Array.prototype
.forEach;
}
}
var moveKey = function (id, parentId) { return id + "@" + parentId; };
function isINode(n) {
return '__sn' in n;
}
var MutationBuffer = (function () {
function MutationBuffer(cb, blockClass, inlineStylesheet, maskInputOptions) {
var _this = this;
this.texts = [];
this.attributes = [];
this.removes = [];
this.adds = [];
this.movedMap = {};
this.addedSet = new Set();
this.movedSet = new Set();
this.droppedSet = new Set();
this.processMutations = function (mutations) {
var e_1, _a, e_2, _b;
mutations.forEach(_this.processMutation);
var addQueue = [];
var pushAdd = function (n) {
if (!n.parentNode) {
return;
}
var parentId = mirror.getId(n.parentNode);
var nextId = n.nextSibling && mirror.getId(n.nextSibling);
if (parentId === -1 || nextId === -1) {
return addQueue.push(n);
}
_this.adds.push({
parentId: parentId,
nextId: nextId,
node: serializeNodeWithId(n, document, mirror.map, _this.blockClass, true, _this.inlineStylesheet, _this.maskInputOptions),
});
};
try {
for (var _c = __values(_this.movedSet), _d = _c.next(); !_d.done; _d = _c.next()) {
var n = _d.value;
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; }
}
while (addQueue.length) {
if (addQueue.every(function (n) { return mirror.getId(n.parentNode) === -1; })) {
break;
}
pushAdd(addQueue.shift());
}
_this.emit();
};
this.emit = function () {
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: _this.adds,
};
if (!payload.texts.length &&
!payload.attributes.length &&
!payload.removes.length &&
!payload.adds.length) {
return;
}
_this.emissionCallback(payload);
_this.texts = [];
_this.attributes = [];
_this.removes = [];
_this.adds = [];
_this.addedSet = new Set();
_this.movedSet = new Set();
_this.droppedSet = new Set();
_this.movedMap = {};
};
this.processMutation = function (m) {
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)) {
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,
});
}
mirror.removeNodeFromMap(n);
});
break;
}
}
};
this.genAdds = function (n, target) {
if (isBlocked(n, _this.blockClass)) {
return;
}
if (isINode(n)) {
_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); });
};
this.blockClass = blockClass;
this.inlineStylesheet = inlineStylesheet;
this.maskInputOptions = maskInputOptions;
this.emissionCallback = cb;
}
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 initMutationObserver(cb, blockClass, inlineStylesheet, maskInputOptions) {
var mutationBuffer = new MutationBuffer(cb, blockClass, inlineStylesheet, maskInputOptions);
var observer = new MutationObserver(mutationBuffer.processMutations);
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.documentElement);
cb({
id: id,
x: scrollEl.scrollLeft,
y: scrollEl.scrollTop,
});
}
else {
cb({
id: id,
x: evt.target.scrollLeft,
y: evt.target.scrollTop,
});
}
}, sampling.scroll || 100);
return on('scroll', updatePosition);
}
function initViewportResizeObserver(cb) {
var updateDimension = throttle(function () {
var height = getWindowHeight();
var width = getWindowWidth();
cb({
width: Number(width),
height: Number(height),
});
}, 200);
return on('resize', updateDimension, window);
}
var INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];
var lastInputValueMap = new WeakMap();
function initInputObserver(cb, blockClass, ignoreClass, maskInputOptions, sampling) {
function eventHandler(event) {
var target = event.target;
if (!target ||
!target.tagName ||
INPUT_TAGS.indexOf(target.tagName) < 0 ||
isBlocked(target, blockClass)) {
return;
}
var type = target.type;
if (type === 'password' ||
target.classList.contains(ignoreClass)) {
return;
}
var text = target.value;
var isChecked = false;
if (type === 'radio' || type === 'checkbox') {
isChecked = target.checked;
}
else if (maskInputOptions[target.tagName.toLowerCase()] ||
maskInputOptions[type]) {
text = '*'.repeat(text.length);
}
cbWithDedup(target, { text: text, isChecked: isChecked });
var name = target.name;
if (type === 'radio' && name && isChecked) {
document
.querySelectorAll("input[type=\"radio\"][name=\"" + name + "\"]")
.forEach(function (el) {
if (el !== target) {
cbWithDedup(el, {
text: el.value,
isChecked: !isChecked,
});
}
});
}
}
function cbWithDedup(target, v) {
var lastInputValue = lastInputValueMap.get(target);
if (!lastInputValue ||
lastInputValue.text !== v.text ||
lastInputValue.isChecked !== v.isChecked) {
lastInputValueMap.set(target, v);
var id = mirror.getId(target);
cb(__assign(__assign({}, v), { id: id }));
}
}
var events = sampling.input === 'last' ? ['change'] : ['input', 'change'];
var handlers = events.map(function (eventName) { return on(eventName, eventHandler); });
var propertyDescriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value');
var hookProperties = [
[HTMLInputElement.prototype, 'value'],
[HTMLInputElement.prototype, 'checked'],
[HTMLSelectElement.prototype, 'value'],
[HTMLTextAreaElement.prototype, 'value'],
];
if (propertyDescriptor && propertyDescriptor.set) {
handlers.push.apply(handlers, __spread(hookProperties.map(function (p) {
return hookSetter(p[0], p[1], {
set: function () {
eventHandler({ target: this });
},
});
})));
}
return function () {
handlers.forEach(function (h) { return h(); });
};
}
function initStyleSheetObserver(cb) {
var insertRule = CSSStyleSheet.prototype.insertRule;
CSSStyleSheet.prototype.insertRule = function (rule, index) {
var id = mirror.getId(this.ownerNode);
if (id !== -1) {
cb({
id: id,
adds: [{ rule: rule, index: index }],
});
}
return insertRule.apply(this, arguments);
};
var deleteRule = CSSStyleSheet.prototype.deleteRule;
CSSStyleSheet.prototype.deleteRule = function (index) {
var id = mirror.getId(this.ownerNode);
if (id !== -1) {
cb({
id: id,
removes: [{ index: index }],
});
}
return deleteRule.apply(this, arguments);
};
return function () {
CSSStyleSheet.prototype.insertRule = insertRule;
CSSStyleSheet.prototype.deleteRule = deleteRule;
};
}
function initMediaInteractionObserver(mediaInteractionCb, blockClass) {
var handler = function (type) { return function (event) {
var target = event.target;
if (!target || isBlocked(target, blockClass)) {
return;
}
mediaInteractionCb({
type: type === 'play' ? MediaInteractions.Play : MediaInteractions.Pause,
id: mirror.getId(target),
});
}; };
var handlers = [on('play', handler('play')), on('pause', handler('pause'))];
return function () {
handlers.forEach(function (h) { return h(); });
};
}
function mergeHooks(o, hooks) {
var mutationCb = o.mutationCb, mousemoveCb = o.mousemoveCb, mouseInteractionCb = o.mouseInteractionCb, scrollCb = o.scrollCb, viewportResizeCb = o.viewportResizeCb, inputCb = o.inputCb, mediaInteractionCb = o.mediaInteractionCb, styleSheetRuleCb = o.styleSheetRuleCb;
o.mutationCb = function () {
var p = [];
for (var _i = 0; _i < arguments.length; _i++) {
p[_i] = arguments[_i];
}
if (hooks.mutation) {
hooks.mutation.apply(hooks, __spread(p));
}
mutationCb.apply(void 0, __spread(p));
};
o.mousemoveCb = function () {
var p = [];
for (var _i = 0; _i < arguments.length; _i++) {
p[_i] = arguments[_i];
}
if (hooks.mousemove) {
hooks.mousemove.apply(hooks, __spread(p));
}
mousemoveCb.apply(void 0, __spread(p));
};
o.mouseInteractionCb = function () {
var p = [];
for (var _i = 0; _i < arguments.length; _i++) {
p[_i] = arguments[_i];
}
if (hooks.mouseInteraction) {
hooks.mouseInteraction.apply(hooks, __spread(p));
}
mouseInteractionCb.apply(void 0, __spread(p));
};
o.scrollCb = function () {
var p = [];
for (var _i = 0; _i < arguments.length; _i++) {
p[_i] = arguments[_i];
}
if (hooks.scroll) {
hooks.scroll.apply(hooks, __spread(p));
}
scrollCb.apply(void 0, __spread(p));
};
o.viewportResizeCb = function () {
var p = [];
for (var _i = 0; _i < arguments.length; _i++) {
p[_i] = arguments[_i];
}
if (hooks.viewportResize) {
hooks.viewportResize.apply(hooks, __spread(p));
}
viewportResizeCb.apply(void 0, __spread(p));
};
o.inputCb = function () {
var p = [];
for (var _i = 0; _i < arguments.length; _i++) {
p[_i] = arguments[_i];
}
if (hooks.input) {
hooks.input.apply(hooks, __spread(p));
}
inputCb.apply(void 0, __spread(p));
};
o.mediaInteractionCb = function () {
var p = [];
for (var _i = 0; _i < arguments.length; _i++) {
p[_i] = arguments[_i];
}
if (hooks.mediaInteaction) {
hooks.mediaInteaction.apply(hooks, __spread(p));
}
mediaInteractionCb.apply(void 0, __spread(p));
};
o.styleSheetRuleCb = function () {
var p = [];
for (var _i = 0; _i < arguments.length; _i++) {
p[_i] = arguments[_i];
}
if (hooks.styleSheetRule) {
hooks.styleSheetRule.apply(hooks, __spread(p));
}
styleSheetRuleCb.apply(void 0, __spread(p));
};
}
function initObservers(o, hooks) {
if (hooks === void 0) { hooks = {}; }
mergeHooks(o, hooks);
var mutationObserver = initMutationObserver(o.mutationCb, o.blockClass, o.inlineStylesheet, o.maskInputOptions);
var mousemoveHandler = initMoveObserver(o.mousemoveCb, o.sampling);
var mouseInteractionHandler = initMouseInteractionObserver(o.mouseInteractionCb, o.blockClass, o.sampling);
var scrollHandler = initScrollObserver(o.scrollCb, o.blockClass, o.sampling);
var viewportResizeHandler = initViewportResizeObserver(o.viewportResizeCb);
var inputHandler = initInputObserver(o.inputCb, o.blockClass, o.ignoreClass, o.maskInputOptions, o.sampling);
var mediaInteractionHandler = initMediaInteractionObserver(o.mediaInteractionCb, o.blockClass);
var styleSheetObserver = initStyleSheetObserver(o.styleSheetRuleCb);
return function () {
mutationObserver.disconnect();
mousemoveHandler();
mouseInteractionHandler();
scrollHandler();
viewportResizeHandler();
inputHandler();
mediaInteractionHandler();
styleSheetObserver();
};
}
function wrapEvent(e) {
return __assign(__assign({}, e), { timestamp: Date.now() });
}
var wrappedEmit;
function record(options) {
if (options === void 0) { options = {}; }
var emit = options.emit, checkoutEveryNms = options.checkoutEveryNms, checkoutEveryNth = options.checkoutEveryNth, _a = options.blockClass, blockClass = _a === void 0 ? 'rr-block' : _a, _b = options.ignoreClass, ignoreClass = _b === void 0 ? 'rr-ignore' : _b, _c = options.inlineStylesheet, inlineStylesheet = _c === void 0 ? true : _c, maskAllInputs = options.maskAllInputs, _maskInputOptions = options.maskInputOptions, hooks = options.hooks, packFn = options.packFn, _d = options.sampling, sampling = _d === void 0 ? {} : _d, mousemoveWait = options.mousemoveWait;
if (!emit) {
throw new Error('emit function is required');
}
if (mousemoveWait !== undefined && sampling.mousemove === undefined) {
sampling.mousemove = mousemoveWait;
}
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,
}
: _maskInputOptions !== undefined
? _maskInputOptions
: {};
polyfill();
var lastFullSnapshotEvent;
var incrementalSnapshotCount = 0;
wrappedEmit = function (e, isCheckout) {
emit((packFn ? packFn(e) : e), isCheckout);
if (e.type === EventType.FullSnapshot) {
lastFullSnapshotEvent = e;
incrementalSnapshotCount = 0;
}
else if (e.type === EventType.IncrementalSnapshot) {
incrementalSnapshotCount++;
var exceedCount = checkoutEveryNth && incrementalSnapshotCount >= checkoutEveryNth;
var exceedTime = checkoutEveryNms &&
e.timestamp - lastFullSnapshotEvent.timestamp > checkoutEveryNms;
if (exceedCount || exceedTime) {
takeFullSnapshot(true);
}
}
};
function takeFullSnapshot(isCheckout) {
var _a, _b, _c, _d;
if (isCheckout === void 0) { isCheckout = false; }
wrappedEmit(wrapEvent({
type: EventType.Meta,
data: {
href: window.location.href,
width: getWindowWidth(),
height: getWindowHeight(),
},
}), isCheckout);
var _e = __read(snapshot(document, blockClass, inlineStylesheet, maskInputOptions), 2), node = _e[0], idNodeMap = _e[1];
if (!node) {
return console.warn('Failed to snapshot the document');
}
mirror.map = idNodeMap;
wrappedEmit(wrapEvent({
type: EventType.FullSnapshot,
data: {
node: node,
initialOffset: {
left: window.pageXOffset !== undefined
? window.pageXOffset