UNPKG

rrweb

Version:
1,349 lines (1,333 loc) 50 kB
'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 : (document === null || document === void 0 ? void 0 : document.documentElement.scrollLeft) || ((_b = (_a = document === null || document === void 0 ? void 0 : document.body) === null || _a === void 0 ? void 0 : _a.parentElement) === null || _b === void 0 ? void 0 : _b.scrollLeft) || (document === null || document === void 0 ? void 0 : document.body.scrollLeft) || 0, top: window.pageYOffset !== undefined ? window.pageYOffset : (document === null || document === void 0 ? void 0 : document.documentElement.scrollTop) || ((_d = (_c = document === null || document === void 0 ? void 0 : document.body) === null || _c === void 0 ? void 0 : _c.parentElement) === null || _d === void 0 ? void 0 : _d.scrollTop) || (document === null || document === void 0 ? void 0 : document.body.scrollTop) || 0, }, }, })); } try { var handlers_1 = []; handlers_1.push(on('DOMContentLoaded', function () { wrappedEmit(wrapEvent({ type: EventType.DomContentLoaded, data: {}, })); })); var init_1 = function () { takeFullSnapshot(); handlers_1.push(initObservers({ mutationCb: function (m) { return wrappedEmit(wrapEvent({ type: EventType.IncrementalSnapshot, data: __assign({ source: IncrementalSource.Mutation }, m), })); }, mousemoveCb: function (positions, source) { return wrappedEmit(wrapEvent({ type: EventType.IncrementalSnapshot, data: { source: source, positions: positions, }, })); }, mouseInteractionCb: function (d) { return wrappedEmit(wrapEvent({ type: EventType.IncrementalSnapshot, data: __assign({ source: IncrementalSource.MouseInteraction }, d), })); }, scrollCb: function (p) { return wrappedEmit(wrapEvent({ type: EventType.IncrementalSnapshot, data: __assign({ source: IncrementalSource.Scroll }, p), })); }, viewportResizeCb: function (d) { return wrappedEmit(wrapEvent({ type: EventType.IncrementalSnapshot, data: __assign({ source: IncrementalSource.ViewportResize }, d), })); }, inputCb: function (v) { return wrappedEmit(wrapEvent({ type: EventType.IncrementalSnapshot, data: __assign({ source: IncrementalSource.Input }, v), })); }, mediaInteractionCb: function (p) { return wrappedEmit(wrapEvent({ type: EventType.IncrementalSnapshot, data: __assign({ source: IncrementalSource.MediaInteraction }, p), })); }, styleSheetRuleCb: function (r) { return wrappedEmit(wrapEvent({ type: EventType.IncrementalSnapshot, data: __assign({ source: IncrementalSource.StyleSheetRule }, r), })); }, blockClass: blockClass, ignoreClass: ignoreClass, maskInputOptions: maskInputOptions, inlineStylesheet: inlineStylesheet, sampling: sampling, }, hooks)); }; if (document.readyState === 'interactive' || document.readyState === 'complete') { init_1(); } else { handlers_1.push(on('load', function () { wrappedEmit(wrapEvent({ type: EventType.Load, data: {}, })); init_1(); }, window)); } return function () { handlers_1.forEach(function (h) { return h(); }); }; } catch (error) { console.warn(error); } } record.addCustomEvent = function (tag, payload) { if (!wrappedEmit) { throw new Error('please add custom event after start recording'); } wrappedEmit(wrapEvent({ type: EventType.Custom, data: { tag: tag, payload: payload, }, })); }; module.exports = record;