@sentry-internal/rrweb
Version:
record and replay the web
1,503 lines • 217 kB
JavaScript
import { i as isIgnored, a as isBlocked, b as isShadowRoot, c as isSerialized, d as isAncestorRemoved, e as isNativeShadowDom, g as getInputType, f as getInputValue, s as shouldMaskInput, n as needMaskingText, m as maskInputValue, h as ignoreAttribute, t as transformAttribute, j as toLowerCase, k as closestElementOfNode, l as hasShadowRoot, I as IGNORED_NODE, o as inDom, p as getShadowHost, q as serializeNodeWithId, r as isSerializedIframe, u as isSerializedStylesheet, v as callbackWrapper, w as throttle, x as getWindowScroll, y as on, M as MouseInteractions, z as hookSetter, A as MediaInteractions, B as patch, C as setTimeout$1, D as legacy_isTouchEvent, E as nowTimestamp, F as IncrementalSource, G as getWindowHeight, H as getWindowWidth, J as toUpperCase, P as PointerTypes, K as genId, L as EventType, N as NodeType$2, S as StyleSheetMirror, O as stringifyRule, Q as onRequestAnimationFrame, R as polyfill$1, T as unregisterErrorHandler, U as createMirror$2, V as CanvasManagerNoop, W as snapshot, X as registerErrorHandler, Y as ReplayerEvents, Z as decode, _ as CanvasContext, $ as createCache, a0 as rebuild, a1 as buildNodeWithSN, a2 as queueToResolveTrees, a3 as iterateResolveTree, a4 as uniqueTextMutations, a5 as getPositionsAndIndex, a6 as getNestedRule, a7 as getBaseDimension, a8 as clearTimeout } from "./canvas-manager-B7mHazUr.js";
import { a9, aa } from "./canvas-manager-B7mHazUr.js";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
var __defProp2 = Object.defineProperty;
var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField2 = (obj, key, value) => __defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value);
var NodeType$1 = /* @__PURE__ */ ((NodeType2) => {
NodeType2[NodeType2["Document"] = 0] = "Document";
NodeType2[NodeType2["DocumentType"] = 1] = "DocumentType";
NodeType2[NodeType2["Element"] = 2] = "Element";
NodeType2[NodeType2["Text"] = 3] = "Text";
NodeType2[NodeType2["CDATA"] = 4] = "CDATA";
NodeType2[NodeType2["Comment"] = 5] = "Comment";
return NodeType2;
})(NodeType$1 || {});
let Mirror$1 = class Mirror {
constructor() {
__publicField2(this, "idNodeMap", /* @__PURE__ */ new Map());
__publicField2(this, "nodeMetaMap", /* @__PURE__ */ new WeakMap());
}
getId(n2) {
if (!n2) return -1;
const id = this.getMeta(n2)?.id;
return id ?? -1;
}
getNode(id) {
return this.idNodeMap.get(id) || null;
}
getIds() {
return Array.from(this.idNodeMap.keys());
}
getMeta(n2) {
return this.nodeMetaMap.get(n2) || null;
}
// removes the node from idNodeMap
// doesn't remove the node from nodeMetaMap
removeNodeFromMap(n2) {
const id = this.getId(n2);
this.idNodeMap.delete(id);
if (n2.childNodes) {
n2.childNodes.forEach(
(childNode) => this.removeNodeFromMap(childNode)
);
}
}
has(id) {
return this.idNodeMap.has(id);
}
hasNode(node) {
return this.nodeMetaMap.has(node);
}
add(n2, meta) {
const id = meta.id;
this.idNodeMap.set(id, n2);
this.nodeMetaMap.set(n2, meta);
}
replace(id, n2) {
const oldNode = this.getNode(id);
if (oldNode) {
const meta = this.nodeMetaMap.get(oldNode);
if (meta) this.nodeMetaMap.set(n2, meta);
}
this.idNodeMap.set(id, n2);
}
reset() {
this.idNodeMap = /* @__PURE__ */ new Map();
this.nodeMetaMap = /* @__PURE__ */ new WeakMap();
}
};
function createMirror$1() {
return new Mirror$1();
}
function parseCSSText(cssText) {
const res = {};
const listDelimiter = /;(?![^(]*\))/g;
const propertyDelimiter = /:(.+)/;
const comment = /\/\*.*?\*\//g;
cssText.replace(comment, "").split(listDelimiter).forEach(function(item) {
if (item) {
const tmp = item.split(propertyDelimiter);
tmp.length > 1 && (res[camelize(tmp[0].trim())] = tmp[1].trim());
}
});
return res;
}
function toCSSText(style) {
const properties = [];
for (const name in style) {
const value = style[name];
if (typeof value !== "string") continue;
const normalizedName = hyphenate(name);
properties.push(`${normalizedName}: ${value};`);
}
return properties.join(" ");
}
const camelizeRE = /-([a-z])/g;
const CUSTOM_PROPERTY_REGEX = /^--[a-zA-Z0-9-]+$/;
const camelize = (str) => {
if (CUSTOM_PROPERTY_REGEX.test(str)) return str;
return str.replace(camelizeRE, (_, c2) => c2 ? c2.toUpperCase() : "");
};
const hyphenateRE = /\B([A-Z])/g;
const hyphenate = (str) => {
return str.replace(hyphenateRE, "-$1").toLowerCase();
};
class BaseRRNode {
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
constructor(..._args) {
__publicField(this, "parentElement", null);
__publicField(this, "parentNode", null);
__publicField(this, "ownerDocument");
__publicField(this, "firstChild", null);
__publicField(this, "lastChild", null);
__publicField(this, "previousSibling", null);
__publicField(this, "nextSibling", null);
__publicField(this, "ELEMENT_NODE", 1);
__publicField(this, "TEXT_NODE", 3);
__publicField(this, "nodeType");
__publicField(this, "nodeName");
__publicField(this, "RRNodeType");
}
get childNodes() {
const childNodes = [];
let childIterator = this.firstChild;
while (childIterator) {
childNodes.push(childIterator);
childIterator = childIterator.nextSibling;
}
return childNodes;
}
contains(node) {
if (!(node instanceof BaseRRNode)) return false;
else if (node.ownerDocument !== this.ownerDocument) return false;
else if (node === this) return true;
while (node.parentNode) {
if (node.parentNode === this) return true;
node = node.parentNode;
}
return false;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
appendChild(_newChild) {
throw new Error(
`RRDomException: Failed to execute 'appendChild' on 'RRNode': This RRNode type does not support this method.`
);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
insertBefore(_newChild, _refChild) {
throw new Error(
`RRDomException: Failed to execute 'insertBefore' on 'RRNode': This RRNode type does not support this method.`
);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
removeChild(_node) {
throw new Error(
`RRDomException: Failed to execute 'removeChild' on 'RRNode': This RRNode type does not support this method.`
);
}
toString() {
return "RRNode";
}
}
class BaseRRDocument extends BaseRRNode {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
constructor(...args) {
super(args);
__publicField(this, "nodeType", 9);
__publicField(this, "nodeName", "#document");
__publicField(this, "compatMode", "CSS1Compat");
__publicField(this, "RRNodeType", NodeType$1.Document);
__publicField(this, "textContent", null);
this.ownerDocument = this;
}
get documentElement() {
return this.childNodes.find(
(node) => node.RRNodeType === NodeType$1.Element && node.tagName === "HTML"
) || null;
}
get body() {
return this.documentElement?.childNodes.find(
(node) => node.RRNodeType === NodeType$1.Element && node.tagName === "BODY"
) || null;
}
get head() {
return this.documentElement?.childNodes.find(
(node) => node.RRNodeType === NodeType$1.Element && node.tagName === "HEAD"
) || null;
}
get implementation() {
return this;
}
get firstElementChild() {
return this.documentElement;
}
appendChild(newChild) {
const nodeType = newChild.RRNodeType;
if (nodeType === NodeType$1.Element || nodeType === NodeType$1.DocumentType) {
if (this.childNodes.some((s2) => s2.RRNodeType === nodeType)) {
throw new Error(
`RRDomException: Failed to execute 'appendChild' on 'RRNode': Only one ${nodeType === NodeType$1.Element ? "RRElement" : "RRDoctype"} on RRDocument allowed.`
);
}
}
const child = appendChild(this, newChild);
child.parentElement = null;
return child;
}
insertBefore(newChild, refChild) {
const nodeType = newChild.RRNodeType;
if (nodeType === NodeType$1.Element || nodeType === NodeType$1.DocumentType) {
if (this.childNodes.some((s2) => s2.RRNodeType === nodeType)) {
throw new Error(
`RRDomException: Failed to execute 'insertBefore' on 'RRNode': Only one ${nodeType === NodeType$1.Element ? "RRElement" : "RRDoctype"} on RRDocument allowed.`
);
}
}
const child = insertBefore(this, newChild, refChild);
child.parentElement = null;
return child;
}
removeChild(node) {
return removeChild(this, node);
}
open() {
this.firstChild = null;
this.lastChild = null;
}
close() {
}
/**
* Adhoc implementation for setting xhtml namespace in rebuilt.ts (rrweb-snapshot).
* There are two lines used this function:
* 1. doc.write('\<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ""\>')
* 2. doc.write('\<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" ""\>')
*/
write(content) {
let publicId;
if (content === '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">')
publicId = "-//W3C//DTD XHTML 1.0 Transitional//EN";
else if (content === '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "">')
publicId = "-//W3C//DTD HTML 4.0 Transitional//EN";
if (publicId) {
const doctype = this.createDocumentType("html", publicId, "");
this.open();
this.appendChild(doctype);
}
}
createDocument(_namespace, _qualifiedName, _doctype) {
return new BaseRRDocument();
}
createDocumentType(qualifiedName, publicId, systemId) {
const doctype = new BaseRRDocumentType(qualifiedName, publicId, systemId);
doctype.ownerDocument = this;
return doctype;
}
createElement(tagName) {
const element = new BaseRRElement(tagName);
element.ownerDocument = this;
return element;
}
createElementNS(_namespaceURI, qualifiedName) {
return this.createElement(qualifiedName);
}
createTextNode(data) {
const text = new BaseRRText(data);
text.ownerDocument = this;
return text;
}
createComment(data) {
const comment = new BaseRRComment(data);
comment.ownerDocument = this;
return comment;
}
createCDATASection(data) {
const CDATASection = new BaseRRCDATASection(data);
CDATASection.ownerDocument = this;
return CDATASection;
}
toString() {
return "RRDocument";
}
}
class BaseRRDocumentType extends BaseRRNode {
constructor(qualifiedName, publicId, systemId) {
super();
__publicField(this, "nodeType", 10);
__publicField(this, "RRNodeType", NodeType$1.DocumentType);
__publicField(this, "name");
__publicField(this, "publicId");
__publicField(this, "systemId");
__publicField(this, "textContent", null);
this.name = qualifiedName;
this.publicId = publicId;
this.systemId = systemId;
this.nodeName = qualifiedName;
}
toString() {
return "RRDocumentType";
}
}
class BaseRRElement extends BaseRRNode {
constructor(tagName) {
super();
__publicField(this, "nodeType", 1);
__publicField(this, "RRNodeType", NodeType$1.Element);
__publicField(this, "tagName");
__publicField(this, "attributes", {});
__publicField(this, "shadowRoot", null);
__publicField(this, "scrollLeft");
__publicField(this, "scrollTop");
this.tagName = tagName.toUpperCase();
this.nodeName = tagName.toUpperCase();
}
get textContent() {
let result = "";
this.childNodes.forEach((node) => result += node.textContent);
return result;
}
set textContent(textContent) {
this.firstChild = null;
this.lastChild = null;
this.appendChild(this.ownerDocument.createTextNode(textContent));
}
get classList() {
return new ClassList(
this.attributes.class,
(newClassName) => {
this.attributes.class = newClassName;
}
);
}
get id() {
return this.attributes.id || "";
}
get className() {
return this.attributes.class || "";
}
get style() {
const style = this.attributes.style ? parseCSSText(this.attributes.style) : {};
const hyphenateRE2 = /\B([A-Z])/g;
style.setProperty = (name, value, priority) => {
if (hyphenateRE2.test(name)) return;
const normalizedName = camelize(name);
if (!value) delete style[normalizedName];
else style[normalizedName] = value;
if (priority === "important") style[normalizedName] += " !important";
this.attributes.style = toCSSText(style);
};
style.removeProperty = (name) => {
if (hyphenateRE2.test(name)) return "";
const normalizedName = camelize(name);
const value = style[normalizedName] || "";
delete style[normalizedName];
this.attributes.style = toCSSText(style);
return value;
};
return style;
}
getAttribute(name) {
return this.attributes[name] || null;
}
setAttribute(name, attribute) {
this.attributes[name] = attribute;
}
setAttributeNS(_namespace, qualifiedName, value) {
this.setAttribute(qualifiedName, value);
}
removeAttribute(name) {
delete this.attributes[name];
}
appendChild(newChild) {
return appendChild(this, newChild);
}
insertBefore(newChild, refChild) {
return insertBefore(this, newChild, refChild);
}
removeChild(node) {
return removeChild(this, node);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
attachShadow(_init) {
const shadowRoot = this.ownerDocument.createElement("SHADOWROOT");
this.shadowRoot = shadowRoot;
return shadowRoot;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
dispatchEvent(_event) {
return true;
}
toString() {
let attributeString = "";
for (const attribute in this.attributes) {
attributeString += `${attribute}="${this.attributes[attribute]}" `;
}
return `${this.tagName} ${attributeString}`;
}
}
class BaseRRMediaElement extends BaseRRElement {
constructor() {
super(...arguments);
__publicField(this, "currentTime");
__publicField(this, "volume");
__publicField(this, "paused");
__publicField(this, "muted");
__publicField(this, "playbackRate");
__publicField(this, "loop");
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
attachShadow(_init) {
throw new Error(
`RRDomException: Failed to execute 'attachShadow' on 'RRElement': This RRElement does not support attachShadow`
);
}
play() {
this.paused = false;
}
pause() {
this.paused = true;
}
}
class BaseRRText extends BaseRRNode {
constructor(data) {
super();
__publicField(this, "nodeType", 3);
__publicField(this, "nodeName", "#text");
__publicField(this, "RRNodeType", NodeType$1.Text);
__publicField(this, "data");
this.data = data;
}
get textContent() {
return this.data;
}
set textContent(textContent) {
this.data = textContent;
}
toString() {
return `RRText text=${JSON.stringify(this.data)}`;
}
}
class BaseRRComment extends BaseRRNode {
constructor(data) {
super();
__publicField(this, "nodeType", 8);
__publicField(this, "nodeName", "#comment");
__publicField(this, "RRNodeType", NodeType$1.Comment);
__publicField(this, "data");
this.data = data;
}
get textContent() {
return this.data;
}
set textContent(textContent) {
this.data = textContent;
}
toString() {
return `RRComment text=${JSON.stringify(this.data)}`;
}
}
class BaseRRCDATASection extends BaseRRNode {
constructor(data) {
super();
__publicField(this, "nodeName", "#cdata-section");
__publicField(this, "nodeType", 4);
__publicField(this, "RRNodeType", NodeType$1.CDATA);
__publicField(this, "data");
this.data = data;
}
get textContent() {
return this.data;
}
set textContent(textContent) {
this.data = textContent;
}
toString() {
return `RRCDATASection data=${JSON.stringify(this.data)}`;
}
}
class ClassList {
constructor(classText, onChange) {
__publicField(this, "onChange");
__publicField(this, "classes", []);
__publicField(this, "add", (...classNames) => {
for (const item of classNames) {
const className = String(item);
if (this.classes.indexOf(className) >= 0) continue;
this.classes.push(className);
}
this.onChange && this.onChange(this.classes.join(" "));
});
__publicField(this, "remove", (...classNames) => {
this.classes = this.classes.filter(
(item) => classNames.indexOf(item) === -1
);
this.onChange && this.onChange(this.classes.join(" "));
});
if (classText) {
const classes = classText.trim().split(/\s+/);
this.classes.push(...classes);
}
this.onChange = onChange;
}
}
function appendChild(parent, newChild) {
if (newChild.parentNode) newChild.parentNode.removeChild(newChild);
if (parent.lastChild) {
parent.lastChild.nextSibling = newChild;
newChild.previousSibling = parent.lastChild;
} else {
parent.firstChild = newChild;
newChild.previousSibling = null;
}
parent.lastChild = newChild;
newChild.nextSibling = null;
newChild.parentNode = parent;
newChild.parentElement = parent;
newChild.ownerDocument = parent.ownerDocument;
return newChild;
}
function insertBefore(parent, newChild, refChild) {
if (!refChild) return appendChild(parent, newChild);
if (refChild.parentNode !== parent)
throw new Error(
"Failed to execute 'insertBefore' on 'RRNode': The RRNode before which the new node is to be inserted is not a child of this RRNode."
);
if (newChild === refChild) return newChild;
if (newChild.parentNode) newChild.parentNode.removeChild(newChild);
newChild.previousSibling = refChild.previousSibling;
refChild.previousSibling = newChild;
newChild.nextSibling = refChild;
if (newChild.previousSibling) newChild.previousSibling.nextSibling = newChild;
else parent.firstChild = newChild;
newChild.parentElement = parent;
newChild.parentNode = parent;
newChild.ownerDocument = parent.ownerDocument;
return newChild;
}
function removeChild(parent, child) {
if (child.parentNode !== parent)
throw new Error(
"Failed to execute 'removeChild' on 'RRNode': The RRNode to be removed is not a child of this RRNode."
);
if (child.previousSibling)
child.previousSibling.nextSibling = child.nextSibling;
else parent.firstChild = child.nextSibling;
if (child.nextSibling)
child.nextSibling.previousSibling = child.previousSibling;
else parent.lastChild = child.previousSibling;
child.previousSibling = null;
child.nextSibling = null;
child.parentElement = null;
child.parentNode = null;
return child;
}
var NodeType = /* @__PURE__ */ ((NodeType2) => {
NodeType2[NodeType2["PLACEHOLDER"] = 0] = "PLACEHOLDER";
NodeType2[NodeType2["ELEMENT_NODE"] = 1] = "ELEMENT_NODE";
NodeType2[NodeType2["ATTRIBUTE_NODE"] = 2] = "ATTRIBUTE_NODE";
NodeType2[NodeType2["TEXT_NODE"] = 3] = "TEXT_NODE";
NodeType2[NodeType2["CDATA_SECTION_NODE"] = 4] = "CDATA_SECTION_NODE";
NodeType2[NodeType2["ENTITY_REFERENCE_NODE"] = 5] = "ENTITY_REFERENCE_NODE";
NodeType2[NodeType2["ENTITY_NODE"] = 6] = "ENTITY_NODE";
NodeType2[NodeType2["PROCESSING_INSTRUCTION_NODE"] = 7] = "PROCESSING_INSTRUCTION_NODE";
NodeType2[NodeType2["COMMENT_NODE"] = 8] = "COMMENT_NODE";
NodeType2[NodeType2["DOCUMENT_NODE"] = 9] = "DOCUMENT_NODE";
NodeType2[NodeType2["DOCUMENT_TYPE_NODE"] = 10] = "DOCUMENT_TYPE_NODE";
NodeType2[NodeType2["DOCUMENT_FRAGMENT_NODE"] = 11] = "DOCUMENT_FRAGMENT_NODE";
return NodeType2;
})(NodeType || {});
function getIFrameContentDocument(iframe) {
try {
return iframe.contentDocument;
} catch (e2) {
}
}
function getIFrameContentWindow(iframe) {
try {
return iframe.contentWindow;
} catch (e2) {
}
}
const NAMESPACES = {
svg: "http://www.w3.org/2000/svg",
"xlink:href": "http://www.w3.org/1999/xlink",
xmlns: "http://www.w3.org/2000/xmlns/"
};
const SVGTagMap = {
altglyph: "altGlyph",
altglyphdef: "altGlyphDef",
altglyphitem: "altGlyphItem",
animatecolor: "animateColor",
animatemotion: "animateMotion",
animatetransform: "animateTransform",
clippath: "clipPath",
feblend: "feBlend",
fecolormatrix: "feColorMatrix",
fecomponenttransfer: "feComponentTransfer",
fecomposite: "feComposite",
feconvolvematrix: "feConvolveMatrix",
fediffuselighting: "feDiffuseLighting",
fedisplacementmap: "feDisplacementMap",
fedistantlight: "feDistantLight",
fedropshadow: "feDropShadow",
feflood: "feFlood",
fefunca: "feFuncA",
fefuncb: "feFuncB",
fefuncg: "feFuncG",
fefuncr: "feFuncR",
fegaussianblur: "feGaussianBlur",
feimage: "feImage",
femerge: "feMerge",
femergenode: "feMergeNode",
femorphology: "feMorphology",
feoffset: "feOffset",
fepointlight: "fePointLight",
fespecularlighting: "feSpecularLighting",
fespotlight: "feSpotLight",
fetile: "feTile",
feturbulence: "feTurbulence",
foreignobject: "foreignObject",
glyphref: "glyphRef",
lineargradient: "linearGradient",
radialgradient: "radialGradient"
};
let createdNodeSet = null;
function diff(oldTree, newTree, replayer, rrnodeMirror = newTree.mirror || newTree.ownerDocument.mirror) {
oldTree = diffBeforeUpdatingChildren(
oldTree,
newTree,
replayer,
rrnodeMirror
);
diffChildren(oldTree, newTree, replayer, rrnodeMirror);
diffAfterUpdatingChildren(oldTree, newTree, replayer);
}
function diffBeforeUpdatingChildren(oldTree, newTree, replayer, rrnodeMirror) {
if (replayer.afterAppend && !createdNodeSet) {
createdNodeSet = /* @__PURE__ */ new WeakSet();
setTimeout(() => {
createdNodeSet = null;
}, 0);
}
if (!sameNodeType(oldTree, newTree)) {
const calibratedOldTree = createOrGetNode(
newTree,
replayer.mirror,
rrnodeMirror
);
oldTree.parentNode?.replaceChild(calibratedOldTree, oldTree);
oldTree = calibratedOldTree;
}
switch (newTree.RRNodeType) {
case NodeType$1.Document: {
if (!nodeMatching(oldTree, newTree, replayer.mirror, rrnodeMirror)) {
const newMeta = rrnodeMirror.getMeta(newTree);
if (newMeta) {
replayer.mirror.removeNodeFromMap(oldTree);
oldTree.close();
oldTree.open();
replayer.mirror.add(oldTree, newMeta);
createdNodeSet?.add(oldTree);
}
}
break;
}
case NodeType$1.Element: {
const oldElement = oldTree;
const newRRElement = newTree;
switch (newRRElement.tagName) {
case "IFRAME": {
const oldContentDocument = getIFrameContentDocument(
oldTree
);
if (!oldContentDocument) break;
diff(
oldContentDocument,
newTree.contentDocument,
replayer,
rrnodeMirror
);
break;
}
}
if (newRRElement.shadowRoot) {
if (!oldElement.shadowRoot) oldElement.attachShadow({ mode: "open" });
diffChildren(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
oldElement.shadowRoot,
newRRElement.shadowRoot,
replayer,
rrnodeMirror
);
}
diffProps(oldElement, newRRElement, rrnodeMirror);
break;
}
}
return oldTree;
}
function diffAfterUpdatingChildren(oldTree, newTree, replayer) {
switch (newTree.RRNodeType) {
case NodeType$1.Document: {
const scrollData = newTree.scrollData;
scrollData && replayer.applyScroll(scrollData, true);
break;
}
case NodeType$1.Element: {
const oldElement = oldTree;
const newRRElement = newTree;
newRRElement.scrollData && replayer.applyScroll(newRRElement.scrollData, true);
newRRElement.inputData && replayer.applyInput(newRRElement.inputData);
switch (newRRElement.tagName) {
case "AUDIO":
case "VIDEO": {
const oldMediaElement = oldTree;
const newMediaRRElement = newRRElement;
if (newMediaRRElement.paused !== void 0) {
const maybePromise = newMediaRRElement.paused ? oldMediaElement.pause() : oldMediaElement.play();
if (typeof maybePromise?.catch === "function") {
maybePromise.catch((e2) => {
console.warn(e2);
});
}
}
if (newMediaRRElement.muted !== void 0)
oldMediaElement.muted = newMediaRRElement.muted;
if (newMediaRRElement.volume !== void 0)
oldMediaElement.volume = newMediaRRElement.volume;
if (newMediaRRElement.currentTime !== void 0)
oldMediaElement.currentTime = newMediaRRElement.currentTime;
if (newMediaRRElement.playbackRate !== void 0)
oldMediaElement.playbackRate = newMediaRRElement.playbackRate;
break;
}
case "CANVAS": {
const rrCanvasElement = newTree;
if (rrCanvasElement.rr_dataURL !== null) {
const image = document.createElement("img");
image.onload = () => {
const ctx = oldElement.getContext("2d");
if (ctx) {
ctx.drawImage(image, 0, 0, image.width, image.height);
}
};
image.src = rrCanvasElement.rr_dataURL;
}
rrCanvasElement.canvasMutations.forEach(
(canvasMutation2) => replayer.applyCanvas(
canvasMutation2.event,
canvasMutation2.mutation,
oldTree
)
);
break;
}
// Props of style elements have to be updated after all children are updated. Otherwise the props can be overwritten by textContent.
case "STYLE": {
const styleSheet = oldElement.sheet;
styleSheet && newTree.rules.forEach(
(data) => replayer.applyStyleSheetMutation(data, styleSheet)
);
break;
}
}
break;
}
case NodeType$1.Text:
case NodeType$1.Comment:
case NodeType$1.CDATA: {
if (oldTree.textContent !== newTree.data)
oldTree.textContent = newTree.data;
break;
}
}
if (createdNodeSet?.has(oldTree)) {
createdNodeSet.delete(oldTree);
replayer.afterAppend?.(oldTree, replayer.mirror.getId(oldTree));
}
}
function diffProps(oldTree, newTree, rrnodeMirror) {
const oldAttributes = oldTree.attributes;
const newAttributes = newTree.attributes;
for (const name in newAttributes) {
const newValue = newAttributes[name];
const sn = rrnodeMirror.getMeta(newTree);
if (sn?.isSVG && NAMESPACES[name])
oldTree.setAttributeNS(NAMESPACES[name], name, newValue);
else if (newTree.tagName === "CANVAS" && name === "rr_dataURL") {
const image = document.createElement("img");
image.src = newValue;
image.onload = () => {
const ctx = oldTree.getContext("2d");
if (ctx) {
ctx.drawImage(image, 0, 0, image.width, image.height);
}
};
} else if (newTree.tagName === "IFRAME" && name === "srcdoc") continue;
else {
try {
oldTree.setAttribute(name, newValue);
} catch (err) {
console.warn(err);
}
}
}
for (const { name } of Array.from(oldAttributes))
if (!(name in newAttributes)) oldTree.removeAttribute(name);
newTree.scrollLeft && (oldTree.scrollLeft = newTree.scrollLeft);
newTree.scrollTop && (oldTree.scrollTop = newTree.scrollTop);
}
function diffChildren(oldTree, newTree, replayer, rrnodeMirror) {
const oldChildren = Array.from(oldTree.childNodes);
const newChildren = newTree.childNodes;
if (oldChildren.length === 0 && newChildren.length === 0) return;
let oldStartIndex = 0, oldEndIndex = oldChildren.length - 1, newStartIndex = 0, newEndIndex = newChildren.length - 1;
let oldStartNode = oldChildren[oldStartIndex], oldEndNode = oldChildren[oldEndIndex], newStartNode = newChildren[newStartIndex], newEndNode = newChildren[newEndIndex];
let oldIdToIndex = void 0, indexInOld = void 0;
while (oldStartIndex <= oldEndIndex && newStartIndex <= newEndIndex) {
if (oldStartNode === void 0) {
oldStartNode = oldChildren[++oldStartIndex];
} else if (oldEndNode === void 0) {
oldEndNode = oldChildren[--oldEndIndex];
} else if (
// same first node?
nodeMatching(oldStartNode, newStartNode, replayer.mirror, rrnodeMirror)
) {
oldStartNode = oldChildren[++oldStartIndex];
newStartNode = newChildren[++newStartIndex];
} else if (
// same last node?
nodeMatching(oldEndNode, newEndNode, replayer.mirror, rrnodeMirror)
) {
oldEndNode = oldChildren[--oldEndIndex];
newEndNode = newChildren[--newEndIndex];
} else if (
// is the first old node the same as the last new node?
nodeMatching(oldStartNode, newEndNode, replayer.mirror, rrnodeMirror)
) {
try {
handleInsertBefore(oldTree, oldStartNode, oldEndNode.nextSibling);
} catch (e2) {
console.warn(e2);
}
oldStartNode = oldChildren[++oldStartIndex];
newEndNode = newChildren[--newEndIndex];
} else if (
// is the last old node the same as the first new node?
nodeMatching(oldEndNode, newStartNode, replayer.mirror, rrnodeMirror)
) {
try {
handleInsertBefore(oldTree, oldEndNode, oldStartNode);
} catch (e2) {
console.warn(e2);
}
oldEndNode = oldChildren[--oldEndIndex];
newStartNode = newChildren[++newStartIndex];
} else {
if (!oldIdToIndex) {
oldIdToIndex = {};
for (let i2 = oldStartIndex; i2 <= oldEndIndex; i2++) {
const oldChild2 = oldChildren[i2];
if (oldChild2 && replayer.mirror.hasNode(oldChild2))
oldIdToIndex[replayer.mirror.getId(oldChild2)] = i2;
}
}
indexInOld = oldIdToIndex[rrnodeMirror.getId(newStartNode)];
const nodeToMove = oldChildren[indexInOld];
if (indexInOld !== void 0 && nodeToMove && nodeMatching(nodeToMove, newStartNode, replayer.mirror, rrnodeMirror)) {
try {
handleInsertBefore(oldTree, nodeToMove, oldStartNode);
} catch (e2) {
console.warn(e2);
}
oldChildren[indexInOld] = void 0;
} else {
const newNode = createOrGetNode(
newStartNode,
replayer.mirror,
rrnodeMirror
);
if (oldTree.nodeName === "#document" && oldStartNode && /**
* Special case 1: one document isn't allowed to have two doctype nodes at the same time, so we need to remove the old one first before inserting the new one.
* How this case happens: A parent document in the old tree already has a doctype node with an id e.g. #1. A new full snapshot rebuilds the replayer with a new doctype node with another id #2. According to the algorithm, the new doctype node will be inserted before the old one, which is not allowed by the Document standard.
*/
(newNode.nodeType === newNode.DOCUMENT_TYPE_NODE && oldStartNode.nodeType === oldStartNode.DOCUMENT_TYPE_NODE || /**
* Special case 2: one document isn't allowed to have two HTMLElements at the same time, so we need to remove the old one first before inserting the new one.
* How this case happens: A mounted iframe element has an automatically created HTML element. We should delete it before inserting a serialized one. Otherwise, an error 'Only one element on document allowed' will be thrown.
*/
newNode.nodeType === newNode.ELEMENT_NODE && oldStartNode.nodeType === oldStartNode.ELEMENT_NODE)) {
oldTree.removeChild(oldStartNode);
replayer.mirror.removeNodeFromMap(oldStartNode);
oldStartNode = oldChildren[++oldStartIndex];
}
try {
handleInsertBefore(oldTree, newNode, oldStartNode || null);
} catch (e2) {
console.warn(e2);
}
}
newStartNode = newChildren[++newStartIndex];
}
}
if (oldStartIndex > oldEndIndex) {
const referenceRRNode = newChildren[newEndIndex + 1];
let referenceNode = null;
if (referenceRRNode)
referenceNode = replayer.mirror.getNode(
rrnodeMirror.getId(referenceRRNode)
);
for (; newStartIndex <= newEndIndex; ++newStartIndex) {
const newNode = createOrGetNode(
newChildren[newStartIndex],
replayer.mirror,
rrnodeMirror
);
try {
handleInsertBefore(oldTree, newNode, referenceNode);
} catch (e2) {
console.warn(e2);
}
}
} else if (newStartIndex > newEndIndex) {
for (; oldStartIndex <= oldEndIndex; oldStartIndex++) {
const node = oldChildren[oldStartIndex];
if (!node || node.parentNode !== oldTree) continue;
try {
oldTree.removeChild(node);
replayer.mirror.removeNodeFromMap(node);
} catch (e2) {
console.warn(e2);
}
}
}
let oldChild = oldTree.firstChild;
let newChild = newTree.firstChild;
while (oldChild !== null && newChild !== null) {
diff(oldChild, newChild, replayer, rrnodeMirror);
oldChild = oldChild.nextSibling;
newChild = newChild.nextSibling;
}
}
function createOrGetNode(rrNode, domMirror, rrnodeMirror) {
const nodeId = rrnodeMirror.getId(rrNode);
const sn = rrnodeMirror.getMeta(rrNode);
let node = null;
if (nodeId > -1) node = domMirror.getNode(nodeId);
if (node !== null && sameNodeType(node, rrNode)) return node;
switch (rrNode.RRNodeType) {
case NodeType$1.Document:
node = new Document();
break;
case NodeType$1.DocumentType:
node = document.implementation.createDocumentType(
rrNode.name,
rrNode.publicId,
rrNode.systemId
);
break;
case NodeType$1.Element: {
let tagName = rrNode.tagName.toLowerCase();
tagName = SVGTagMap[tagName] || tagName;
if (sn && "isSVG" in sn && sn?.isSVG) {
node = document.createElementNS(NAMESPACES["svg"], tagName);
} else node = document.createElement(rrNode.tagName);
break;
}
case NodeType$1.Text:
node = document.createTextNode(rrNode.data);
break;
case NodeType$1.Comment:
node = document.createComment(rrNode.data);
break;
case NodeType$1.CDATA:
node = document.createCDATASection(rrNode.data);
break;
}
if (sn) domMirror.add(node, { ...sn });
try {
createdNodeSet?.add(node);
} catch (e2) {
}
return node;
}
function sameNodeType(node1, node2) {
if (node1.nodeType !== node2.nodeType) return false;
return node1.nodeType !== node1.ELEMENT_NODE || node1.tagName.toUpperCase() === node2.tagName;
}
function nodeMatching(node1, node2, domMirror, rrdomMirror) {
const node1Id = domMirror.getId(node1);
const node2Id = rrdomMirror.getId(node2);
if (node1Id === -1 || node1Id !== node2Id) return false;
return sameNodeType(node1, node2);
}
function getInsertedStylesFromElement(styleElement) {
const elementCssRules = styleElement.sheet?.cssRules;
if (!elementCssRules || !elementCssRules.length) return;
const tempStyleSheet = new CSSStyleSheet();
tempStyleSheet.replaceSync(styleElement.innerText);
const innerTextStylesMap = {};
for (let i2 = 0; i2 < tempStyleSheet.cssRules.length; i2++) {
innerTextStylesMap[tempStyleSheet.cssRules[i2].cssText] = tempStyleSheet.cssRules[i2];
}
const insertedStylesStyleSheet = [];
for (let i2 = 0; i2 < elementCssRules?.length; i2++) {
const cssRuleText = elementCssRules[i2].cssText;
if (!innerTextStylesMap[cssRuleText]) {
insertedStylesStyleSheet.push({
index: i2,
cssRuleText
});
}
}
return insertedStylesStyleSheet;
}
function handleInsertBefore(oldTree, nodeToMove, insertBeforeNode) {
let insertedStyles;
if (nodeToMove.nodeName === "STYLE") {
insertedStyles = getInsertedStylesFromElement(
nodeToMove
);
}
oldTree.insertBefore(nodeToMove, insertBeforeNode);
if (insertedStyles && insertedStyles.length) {
insertedStyles.forEach(({ cssRuleText, index }) => {
nodeToMove.sheet?.insertRule(cssRuleText, index);
});
}
}
class RRDocument extends BaseRRDocument {
constructor(mirror2) {
super();
__publicField(this, "UNSERIALIZED_STARTING_ID", -2);
__publicField(this, "_unserializedId", this.UNSERIALIZED_STARTING_ID);
__publicField(this, "mirror", createMirror());
__publicField(this, "scrollData", null);
if (mirror2) {
this.mirror = mirror2;
}
}
/**
* Every time the id is used, it will minus 1 automatically to avoid collisions.
*/
get unserializedId() {
return this._unserializedId--;
}
createDocument(_namespace, _qualifiedName, _doctype) {
return new RRDocument();
}
createDocumentType(qualifiedName, publicId, systemId) {
const documentTypeNode = new RRDocumentType(
qualifiedName,
publicId,
systemId
);
documentTypeNode.ownerDocument = this;
return documentTypeNode;
}
createElement(tagName) {
const upperTagName = tagName.toUpperCase();
let element;
switch (upperTagName) {
case "AUDIO":
case "VIDEO":
element = new RRMediaElement(upperTagName);
break;
case "IFRAME":
element = new RRIFrameElement(upperTagName, this.mirror);
break;
case "CANVAS":
element = new RRCanvasElement(upperTagName);
break;
case "STYLE":
element = new RRStyleElement(upperTagName);
break;
default:
element = new RRElement(upperTagName);
break;
}
element.ownerDocument = this;
return element;
}
createComment(data) {
const commentNode = new RRComment(data);
commentNode.ownerDocument = this;
return commentNode;
}
createCDATASection(data) {
const sectionNode = new RRCDATASection(data);
sectionNode.ownerDocument = this;
return sectionNode;
}
createTextNode(data) {
const textNode = new RRText(data);
textNode.ownerDocument = this;
return textNode;
}
destroyTree() {
this.firstChild = null;
this.lastChild = null;
this.mirror.reset();
}
open() {
super.open();
this._unserializedId = this.UNSERIALIZED_STARTING_ID;
}
}
const RRDocumentType = BaseRRDocumentType;
class RRElement extends BaseRRElement {
constructor() {
super(...arguments);
__publicField(this, "inputData", null);
__publicField(this, "scrollData", null);
}
}
class RRMediaElement extends BaseRRMediaElement {
}
class RRCanvasElement extends RRElement {
constructor() {
super(...arguments);
__publicField(this, "rr_dataURL", null);
__publicField(this, "canvasMutations", []);
}
/**
* This is a dummy implementation to distinguish RRCanvasElement from real HTMLCanvasElement.
*/
getContext() {
return null;
}
}
class RRStyleElement extends RRElement {
constructor() {
super(...arguments);
__publicField(this, "rules", []);
}
}
class RRIFrameElement extends RRElement {
constructor(upperTagName, mirror2) {
super(upperTagName);
__publicField(this, "contentDocument", new RRDocument());
this.contentDocument.mirror = mirror2;
}
}
const RRText = BaseRRText;
const RRComment = BaseRRComment;
const RRCDATASection = BaseRRCDATASection;
function getValidTagName(element) {
if (element instanceof HTMLFormElement) {
return "FORM";
}
return element.tagName.toUpperCase();
}
function buildFromNode(node, rrdom, domMirror, parentRRNode) {
let rrNode;
switch (node.nodeType) {
case NodeType.DOCUMENT_NODE:
if (parentRRNode && parentRRNode.nodeName === "IFRAME")
rrNode = parentRRNode.contentDocument;
else {
rrNode = rrdom;
rrNode.compatMode = node.compatMode;
}
break;
case NodeType.DOCUMENT_TYPE_NODE: {
const documentType = node;
rrNode = rrdom.createDocumentType(
documentType.name,
documentType.publicId,
documentType.systemId
);
break;
}
case NodeType.ELEMENT_NODE: {
const elementNode = node;
const tagName = getValidTagName(elementNode);
rrNode = rrdom.createElement(tagName);
const rrElement = rrNode;
for (const { name, value } of Array.from(elementNode.attributes)) {
rrElement.attributes[name] = value;
}
elementNode.scrollLeft && (rrElement.scrollLeft = elementNode.scrollLeft);
elementNode.scrollTop && (rrElement.scrollTop = elementNode.scrollTop);
break;
}
case NodeType.TEXT_NODE:
rrNode = rrdom.createTextNode(node.textContent || "");
break;
case NodeType.CDATA_SECTION_NODE:
rrNode = rrdom.createCDATASection(node.data);
break;
case NodeType.COMMENT_NODE:
rrNode = rrdom.createComment(node.textContent || "");
break;
// if node is a shadow root
case NodeType.DOCUMENT_FRAGMENT_NODE:
rrNode = parentRRNode.attachShadow({ mode: "open" });
break;
default:
return null;
}
let sn = domMirror.getMeta(node);
if (rrdom instanceof RRDocument) {
if (!sn) {
sn = getDefaultSN(rrNode, rrdom.unserializedId);
domMirror.add(node, sn);
}
rrdom.mirror.add(rrNode, { ...sn });
}
return rrNode;
}
function buildFromDom(dom, domMirror = createMirror$1(), rrdom = new RRDocument()) {
function walk2(node, parentRRNode) {
const rrNode = buildFromNode(node, rrdom, domMirror, parentRRNode);
if (rrNode === null) return;
if (
// if the parentRRNode isn't a RRIFrameElement
parentRRNode?.nodeName !== "IFRAME" && // if node isn't a shadow root
node.nodeType !== NodeType.DOCUMENT_FRAGMENT_NODE
) {
parentRRNode?.appendChild(rrNode);
rrNode.parentNode = parentRRNode;
rrNode.parentElement = parentRRNode;
}
if (node.nodeName === "IFRAME") {
const iframeDoc = getIFrameContentDocument(node);
iframeDoc && walk2(iframeDoc, rrNode);
} else if (node.nodeType === NodeType.DOCUMENT_NODE || node.nodeType === NodeType.ELEMENT_NODE || node.nodeType === NodeType.DOCUMENT_FRAGMENT_NODE) {
if (node.nodeType === NodeType.ELEMENT_NODE && node.shadowRoot)
walk2(node.shadowRoot, rrNode);
node.childNodes.forEach((childNode) => walk2(childNode, rrNode));
}
}
walk2(dom, null);
return rrdom;
}
function createMirror() {
return new Mirror2();
}
class Mirror2 {
constructor() {
__publicField(this, "idNodeMap", /* @__PURE__ */ new Map());
__publicField(this, "nodeMetaMap", /* @__PURE__ */ new WeakMap());
}
getId(n2) {
if (!n2) return -1;
const id = this.getMeta(n2)?.id;
return id ?? -1;
}
getNode(id) {
return this.idNodeMap.get(id) || null;
}
getIds() {
return Array.from(this.idNodeMap.keys());
}
getMeta(n2) {
return this.nodeMetaMap.get(n2) || null;
}
// removes the node from idNodeMap
// doesn't remove the node from nodeMetaMap
removeNodeFromMap(n2) {
const id = this.getId(n2);
this.idNodeMap.delete(id);
if (n2.childNodes) {
n2.childNodes.forEach((childNode) => this.removeNodeFromMap(childNode));
}
}
has(id) {
return this.idNodeMap.has(id);
}
hasNode(node) {
return this.nodeMetaMap.has(node);
}
add(n2, meta) {
const id = meta.id;
this.idNodeMap.set(id, n2);
this.nodeMetaMap.set(n2, meta);
}
replace(id, n2) {
const oldNode = this.getNode(id);
if (oldNode) {
const meta = this.nodeMetaMap.get(oldNode);
if (meta) this.nodeMetaMap.set(n2, meta);
}
this.idNodeMap.set(id, n2);
}
reset() {
this.idNodeMap = /* @__PURE__ */ new Map();
this.nodeMetaMap = /* @__PURE__ */ new WeakMap();
}
}
function getDefaultSN(node, id) {
switch (node.RRNodeType) {
case NodeType$1.Document:
return {
id,
type: node.RRNodeType,
childNodes: []
};
case NodeType$1.DocumentType: {
const doctype = node;
return {
id,
type: node.RRNodeType,
name: doctype.name,
publicId: doctype.publicId,
systemId: doctype.systemId
};
}
case NodeType$1.Element:
return {
id,
type: node.RRNodeType,
tagName: node.tagName.toLowerCase(),
// In rrweb data, all tagNames are lowercase.
attributes: {},
childNodes: []
};
case NodeType$1.Text:
return {
id,
type: node.RRNodeType,
textContent: node.textContent || ""
};
case NodeType$1.Comment:
return {
id,
type: node.RRNodeType,
textContent: node.textContent || ""
};
case NodeType$1.CDATA:
return {
id,
type: node.RRNodeType,
textContent: ""
};
}
}
class StyleDeclarationParser {
constructor(doc) {
this.doc = doc;
this.unattachedDoc = null;
}
parse(styleText) {
return this.parseWithConstructableStylesheet(styleText) || this.parseWithDetachedElement(styleText);
}
parseWithConstructableStylesheet(styleText) {
if (typeof CSSStyleSheet === "undefined" || typeof CSSStyleSheet.prototype.replaceSync !== "function") {
return null;
}
try {
const sheet = new CSSStyleSheet();
sheet.replaceSync(`x { ${styleText} }`);
const rule = sheet.cssRules[0];
if (!rule || rule.type !== CSSRule.STYLE_RULE) {
return null;
}
return rule.style;
} catch {
return null;
}
}
parseWithDetachedElement(styleText) {
const old = this.getUnattachedDoc().createElement("span");
old.setAttribute("style", styleText);
return old.style;
}
getUnattachedDoc() {
if (!this.unattachedDoc) {
try {
this.unattachedDoc = document.implementation.createHTMLDocument();
} catch {
this.unattachedDoc = this.doc;
}
}
return this.unattachedDoc;
}
}
function isNodeInLinkedList(n2) {
return "__ln" in n2;
}
class DoubleLinkedList {
constructor() {
this.length = 0;
this.head = null;
this.tail = null;
}
get(position) {
if (position >= this.length) {
throw new Error("Position outside of list range");
}
let current = this.head;
for (let index = 0; index < position; index++) {
current = current?.next || null;
}
return current;
}
addNode(n2) {
const node = {
value: n2,
previous: null,
next: null
};
n2.__ln = node;
if (n2.previousSibling && isNodeInLinkedList(n2.previousSibling)) {
const current = n2.previousSibling.__ln.next;
node.next = current;
node.previous = n2.previousSibling.__ln;
n2.previousSibling.__ln.next = node;
if (current) {
current.previous = node;
}
} else if (n2.nextSibling && isNodeInLinkedList(n2.nextSibling) && n2.nextSibling.__ln.previous) {
const current = n2.nextSibling.__ln.previous;
node.previous = current;
node.next = n2.nextSibling.__ln;
n2.nextSibling.__ln.previous = node;
if (current) {
current.next = node;
}
} else {
if (this.head) {
this.head.previous = node;
}
node.next = this.head;
this.head = node;
}
if (node.next === null) {
this.tail = node;
}
this.length++;
}
removeNode(n2) {
const current = n2.__ln;
if (!this.head) {
return;
}
if (!current.previous) {
this.head = current.next;
if (this.head) {
this.head.previous = null;
} else {
this.tail = null;
}
} else {
current.previous.next = current.next;
if (current.next) {
current.next.previous = current.previous;
} else {
this.tail = current.previous;
}
}
if (n2.__ln) {
delete n2.__ln;
}
this.length--;
}
}
const moveKey = (id, parentId) => `${id}@${parentId}`;
class MutationBuffer {
constructor() {
this.frozen = false;
this.locked = false;
this.texts = [];
this.attributes = [];
this.attributeMap = /* @__PURE__ */ new WeakMap();
this.removes = [];
this.mapRemoves = [];
this.movedMap = {};
this.addedSet = /* @__PURE__ */ new Set();
this.movedSet = /* @__PURE__ */ new Set();
this.droppedSet = /* @__PURE__ */ new Set();
this.processMutations = (mutations) => {
mutations.forEach(this.processMutation);
this.emit();
};
this.emit = () => {
if (this.frozen || this.locked) {
return;
}
const adds = [];
const addedIds = /* @__PURE__ */ new Set();
const addList = new DoubleLinkedList();
const getNextId = (n2) => {
let ns = n2;
let nextId = IGNORED_NODE;
while (nextId === IGNORED_NODE) {
ns = ns && ns.nextSibling;
nextId = ns && this.mirror.getId(ns);
}
return nextId;
};
const pushAdd = (n2) => {
if (!n2.parentNode || !inDom(n2)) {
return;
}
const parentId = isShadowRoot(n2.parentNode) ? this.mirror.getId(getShadowHost(n2)) : this.mirror.getId(n2.parentNode);
const nextId = getNextId(n2);
if (parentId === -1 || nextId === -1) {
return addList.addNode(n2);
}
const sn = serializeNodeWithId(n2, {
doc: this.doc,
mirror: this.mir