rrweb
Version:
record and replay the web
1,435 lines (1,433 loc) • 171 kB
JavaScript
var rrwebReplay = (function (exports) {
'use strict';
var NodeType$2;
(function(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";
})(NodeType$2 || (NodeType$2 = {}));
function isElement(n) {
return n.nodeType === n.ELEMENT_NODE;
}
var Mirror$2 = function() {
function Mirror2() {
this.idNodeMap = /* @__PURE__ */ new Map();
this.nodeMetaMap = /* @__PURE__ */ new WeakMap();
}
Mirror2.prototype.getId = function(n) {
var _a;
if (!n)
return -1;
var id = (_a = this.getMeta(n)) === null || _a === void 0 ? void 0 : _a.id;
return id !== null && id !== void 0 ? id : -1;
};
Mirror2.prototype.getNode = function(id) {
return this.idNodeMap.get(id) || null;
};
Mirror2.prototype.getIds = function() {
return Array.from(this.idNodeMap.keys());
};
Mirror2.prototype.getMeta = function(n) {
return this.nodeMetaMap.get(n) || null;
};
Mirror2.prototype.removeNodeFromMap = function(n) {
var _this = this;
var id = this.getId(n);
this.idNodeMap["delete"](id);
if (n.childNodes) {
n.childNodes.forEach(function(childNode) {
return _this.removeNodeFromMap(childNode);
});
}
};
Mirror2.prototype.has = function(id) {
return this.idNodeMap.has(id);
};
Mirror2.prototype.hasNode = function(node) {
return this.nodeMetaMap.has(node);
};
Mirror2.prototype.add = function(n, meta) {
var id = meta.id;
this.idNodeMap.set(id, n);
this.nodeMetaMap.set(n, meta);
};
Mirror2.prototype.replace = function(id, n) {
var oldNode = this.getNode(id);
if (oldNode) {
var meta = this.nodeMetaMap.get(oldNode);
if (meta)
this.nodeMetaMap.set(n, meta);
}
this.idNodeMap.set(id, n);
};
Mirror2.prototype.reset = function() {
this.idNodeMap = /* @__PURE__ */ new Map();
this.nodeMetaMap = /* @__PURE__ */ new WeakMap();
};
return Mirror2;
}();
function createMirror$2() {
return new Mirror$2();
}
var commentre = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g;
function parse(css, options) {
if (options === void 0) {
options = {};
}
var lineno = 1;
var column = 1;
function updatePosition(str) {
var lines = str.match(/\n/g);
if (lines) {
lineno += lines.length;
}
var i = str.lastIndexOf("\n");
column = i === -1 ? column + str.length : str.length - i;
}
function position() {
var start = { line: lineno, column };
return function(node) {
node.position = new Position(start);
whitespace();
return node;
};
}
var Position = function() {
function Position2(start) {
this.start = start;
this.end = { line: lineno, column };
this.source = options.source;
}
return Position2;
}();
Position.prototype.content = css;
var errorsList = [];
function error(msg) {
var err = new Error("".concat(options.source || "", ":").concat(lineno, ":").concat(column, ": ").concat(msg));
err.reason = msg;
err.filename = options.source;
err.line = lineno;
err.column = column;
err.source = css;
if (options.silent) {
errorsList.push(err);
} else {
throw err;
}
}
function stylesheet() {
var rulesList = rules();
return {
type: "stylesheet",
stylesheet: {
source: options.source,
rules: rulesList,
parsingErrors: errorsList
}
};
}
function open() {
return match(/^{\s*/);
}
function close() {
return match(/^}/);
}
function rules() {
var node;
var rules2 = [];
whitespace();
comments(rules2);
while (css.length && css.charAt(0) !== "}" && (node = atrule() || rule())) {
if (node !== false) {
rules2.push(node);
comments(rules2);
}
}
return rules2;
}
function match(re) {
var m = re.exec(css);
if (!m) {
return;
}
var str = m[0];
updatePosition(str);
css = css.slice(str.length);
return m;
}
function whitespace() {
match(/^\s*/);
}
function comments(rules2) {
if (rules2 === void 0) {
rules2 = [];
}
var c;
while (c = comment()) {
if (c !== false) {
rules2.push(c);
}
c = comment();
}
return rules2;
}
function comment() {
var pos = position();
if (css.charAt(0) !== "/" || css.charAt(1) !== "*") {
return;
}
var i = 2;
while (css.charAt(i) !== "" && (css.charAt(i) !== "*" || css.charAt(i + 1) !== "/")) {
++i;
}
i += 2;
if (css.charAt(i - 1) === "") {
return error("End of comment missing");
}
var str = css.slice(2, i - 2);
column += 2;
updatePosition(str);
css = css.slice(i);
column += 2;
return pos({
type: "comment",
comment: str
});
}
function selector() {
var m = match(/^([^{]+)/);
if (!m) {
return;
}
return trim(m[0]).replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, "").replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, function(m2) {
return m2.replace(/,/g, "\u200C");
}).split(/\s*(?![^(]*\)),\s*/).map(function(s) {
return s.replace(/\u200C/g, ",");
});
}
function declaration() {
var pos = position();
var propMatch = match(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/);
if (!propMatch) {
return;
}
var prop = trim(propMatch[0]);
if (!match(/^:\s*/)) {
return error("property missing ':'");
}
var val = match(/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+)/);
var ret = pos({
type: "declaration",
property: prop.replace(commentre, ""),
value: val ? trim(val[0]).replace(commentre, "") : ""
});
match(/^[;\s]*/);
return ret;
}
function declarations() {
var decls = [];
if (!open()) {
return error("missing '{'");
}
comments(decls);
var decl;
while (decl = declaration()) {
if (decl !== false) {
decls.push(decl);
comments(decls);
}
decl = declaration();
}
if (!close()) {
return error("missing '}'");
}
return decls;
}
function keyframe() {
var m;
var vals = [];
var pos = position();
while (m = match(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/)) {
vals.push(m[1]);
match(/^,\s*/);
}
if (!vals.length) {
return;
}
return pos({
type: "keyframe",
values: vals,
declarations: declarations()
});
}
function atkeyframes() {
var pos = position();
var m = match(/^@([-\w]+)?keyframes\s*/);
if (!m) {
return;
}
var vendor = m[1];
m = match(/^([-\w]+)\s*/);
if (!m) {
return error("@keyframes missing name");
}
var name = m[1];
if (!open()) {
return error("@keyframes missing '{'");
}
var frame;
var frames = comments();
while (frame = keyframe()) {
frames.push(frame);
frames = frames.concat(comments());
}
if (!close()) {
return error("@keyframes missing '}'");
}
return pos({
type: "keyframes",
name,
vendor,
keyframes: frames
});
}
function atsupports() {
var pos = position();
var m = match(/^@supports *([^{]+)/);
if (!m) {
return;
}
var supports = trim(m[1]);
if (!open()) {
return error("@supports missing '{'");
}
var style = comments().concat(rules());
if (!close()) {
return error("@supports missing '}'");
}
return pos({
type: "supports",
supports,
rules: style
});
}
function athost() {
var pos = position();
var m = match(/^@host\s*/);
if (!m) {
return;
}
if (!open()) {
return error("@host missing '{'");
}
var style = comments().concat(rules());
if (!close()) {
return error("@host missing '}'");
}
return pos({
type: "host",
rules: style
});
}
function atmedia() {
var pos = position();
var m = match(/^@media *([^{]+)/);
if (!m) {
return;
}
var media = trim(m[1]);
if (!open()) {
return error("@media missing '{'");
}
var style = comments().concat(rules());
if (!close()) {
return error("@media missing '}'");
}
return pos({
type: "media",
media,
rules: style
});
}
function atcustommedia() {
var pos = position();
var m = match(/^@custom-media\s+(--[^\s]+)\s*([^{;]+);/);
if (!m) {
return;
}
return pos({
type: "custom-media",
name: trim(m[1]),
media: trim(m[2])
});
}
function atpage() {
var pos = position();
var m = match(/^@page */);
if (!m) {
return;
}
var sel = selector() || [];
if (!open()) {
return error("@page missing '{'");
}
var decls = comments();
var decl;
while (decl = declaration()) {
decls.push(decl);
decls = decls.concat(comments());
}
if (!close()) {
return error("@page missing '}'");
}
return pos({
type: "page",
selectors: sel,
declarations: decls
});
}
function atdocument() {
var pos = position();
var m = match(/^@([-\w]+)?document *([^{]+)/);
if (!m) {
return;
}
var vendor = trim(m[1]);
var doc = trim(m[2]);
if (!open()) {
return error("@document missing '{'");
}
var style = comments().concat(rules());
if (!close()) {
return error("@document missing '}'");
}
return pos({
type: "document",
document: doc,
vendor,
rules: style
});
}
function atfontface() {
var pos = position();
var m = match(/^@font-face\s*/);
if (!m) {
return;
}
if (!open()) {
return error("@font-face missing '{'");
}
var decls = comments();
var decl;
while (decl = declaration()) {
decls.push(decl);
decls = decls.concat(comments());
}
if (!close()) {
return error("@font-face missing '}'");
}
return pos({
type: "font-face",
declarations: decls
});
}
var atimport = _compileAtrule("import");
var atcharset = _compileAtrule("charset");
var atnamespace = _compileAtrule("namespace");
function _compileAtrule(name) {
var re = new RegExp("^@" + name + "\\s*([^;]+);");
return function() {
var pos = position();
var m = match(re);
if (!m) {
return;
}
var ret = { type: name };
ret[name] = m[1].trim();
return pos(ret);
};
}
function atrule() {
if (css[0] !== "@") {
return;
}
return atkeyframes() || atmedia() || atcustommedia() || atsupports() || atimport() || atcharset() || atnamespace() || atdocument() || atpage() || athost() || atfontface();
}
function rule() {
var pos = position();
var sel = selector();
if (!sel) {
return error("selector missing");
}
comments();
return pos({
type: "rule",
selectors: sel,
declarations: declarations()
});
}
return addParent(stylesheet());
}
function trim(str) {
return str ? str.replace(/^\s+|\s+$/g, "") : "";
}
function addParent(obj, parent) {
var isNode = obj && typeof obj.type === "string";
var childParent = isNode ? obj : parent;
for (var _i = 0, _a = Object.keys(obj); _i < _a.length; _i++) {
var k = _a[_i];
var value = obj[k];
if (Array.isArray(value)) {
value.forEach(function(v) {
addParent(v, childParent);
});
} else if (value && typeof value === "object") {
addParent(value, childParent);
}
}
if (isNode) {
Object.defineProperty(obj, "parent", {
configurable: true,
writable: true,
enumerable: false,
value: parent || null
});
}
return obj;
}
var tagMap = {
script: "noscript",
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"
};
function getTagName(n) {
var tagName = tagMap[n.tagName] ? tagMap[n.tagName] : n.tagName;
if (tagName === "link" && n.attributes._cssText) {
tagName = "style";
}
return tagName;
}
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
var HOVER_SELECTOR = /([^\\]):hover/;
var HOVER_SELECTOR_GLOBAL = new RegExp(HOVER_SELECTOR.source, "g");
function addHoverClass(cssText, cache) {
var cachedStyle = cache === null || cache === void 0 ? void 0 : cache.stylesWithHoverClass.get(cssText);
if (cachedStyle)
return cachedStyle;
var ast = parse(cssText, {
silent: true
});
if (!ast.stylesheet) {
return cssText;
}
var selectors = [];
ast.stylesheet.rules.forEach(function(rule) {
if ("selectors" in rule) {
(rule.selectors || []).forEach(function(selector) {
if (HOVER_SELECTOR.test(selector)) {
selectors.push(selector);
}
});
}
});
if (selectors.length === 0) {
return cssText;
}
var selectorMatcher = new RegExp(selectors.filter(function(selector, index) {
return selectors.indexOf(selector) === index;
}).sort(function(a, b) {
return b.length - a.length;
}).map(function(selector) {
return escapeRegExp(selector);
}).join("|"), "g");
var result = cssText.replace(selectorMatcher, function(selector) {
var newSelector = selector.replace(HOVER_SELECTOR_GLOBAL, "$1.\\:hover");
return "".concat(selector, ", ").concat(newSelector);
});
cache === null || cache === void 0 ? void 0 : cache.stylesWithHoverClass.set(cssText, result);
return result;
}
function createCache() {
var stylesWithHoverClass = /* @__PURE__ */ new Map();
return {
stylesWithHoverClass
};
}
function buildNode(n, options) {
var doc = options.doc, hackCss = options.hackCss, cache = options.cache;
switch (n.type) {
case NodeType$2.Document:
return doc.implementation.createDocument(null, "", null);
case NodeType$2.DocumentType:
return doc.implementation.createDocumentType(n.name || "html", n.publicId, n.systemId);
case NodeType$2.Element: {
var tagName = getTagName(n);
var node_1;
if (n.isSVG) {
node_1 = doc.createElementNS("http://www.w3.org/2000/svg", tagName);
} else {
node_1 = doc.createElement(tagName);
}
var specialAttributes = {};
for (var name_1 in n.attributes) {
if (!Object.prototype.hasOwnProperty.call(n.attributes, name_1)) {
continue;
}
var value = n.attributes[name_1];
if (tagName === "option" && name_1 === "selected" && value === false) {
continue;
}
if (value === true)
value = "";
if (name_1.startsWith("rr_")) {
specialAttributes[name_1] = value;
continue;
}
var isTextarea = tagName === "textarea" && name_1 === "value";
var isRemoteOrDynamicCss = tagName === "style" && name_1 === "_cssText";
if (isRemoteOrDynamicCss && hackCss && typeof value === "string") {
value = addHoverClass(value, cache);
}
if ((isTextarea || isRemoteOrDynamicCss) && typeof value === "string") {
var child = doc.createTextNode(value);
for (var _i = 0, _a = Array.from(node_1.childNodes); _i < _a.length; _i++) {
var c = _a[_i];
if (c.nodeType === node_1.TEXT_NODE) {
node_1.removeChild(c);
}
}
node_1.appendChild(child);
continue;
}
try {
if (n.isSVG && name_1 === "xlink:href") {
node_1.setAttributeNS("http://www.w3.org/1999/xlink", name_1, value.toString());
} else if (name_1 === "onload" || name_1 === "onclick" || name_1.substring(0, 7) === "onmouse") {
node_1.setAttribute("_" + name_1, value.toString());
} else if (tagName === "meta" && n.attributes["http-equiv"] === "Content-Security-Policy" && name_1 === "content") {
node_1.setAttribute("csp-content", value.toString());
continue;
} else if (tagName === "link" && n.attributes.rel === "preload" && n.attributes.as === "script") {
} else if (tagName === "link" && n.attributes.rel === "prefetch" && typeof n.attributes.href === "string" && n.attributes.href.endsWith(".js")) {
} else if (tagName === "img" && n.attributes.srcset && n.attributes.rr_dataURL) {
node_1.setAttribute("rrweb-original-srcset", n.attributes.srcset);
} else {
node_1.setAttribute(name_1, value.toString());
}
} catch (error) {
}
}
var _loop_1 = function(name_22) {
var value2 = specialAttributes[name_22];
if (tagName === "canvas" && name_22 === "rr_dataURL") {
var image_1 = document.createElement("img");
image_1.onload = function() {
var ctx = node_1.getContext("2d");
if (ctx) {
ctx.drawImage(image_1, 0, 0, image_1.width, image_1.height);
}
};
image_1.src = value2.toString();
if (node_1.RRNodeType)
node_1.rr_dataURL = value2.toString();
} else if (tagName === "img" && name_22 === "rr_dataURL") {
var image = node_1;
if (!image.currentSrc.startsWith("data:")) {
image.setAttribute("rrweb-original-src", n.attributes.src);
image.src = value2.toString();
}
}
if (name_22 === "rr_width") {
node_1.style.width = value2.toString();
} else if (name_22 === "rr_height") {
node_1.style.height = value2.toString();
} else if (name_22 === "rr_mediaCurrentTime" && typeof value2 === "number") {
node_1.currentTime = value2;
} else if (name_22 === "rr_mediaState") {
switch (value2) {
case "played":
node_1.play()["catch"](function(e) {
return console.warn("media playback error", e);
});
break;
case "paused":
node_1.pause();
break;
}
}
};
for (var name_2 in specialAttributes) {
_loop_1(name_2);
}
if (n.isShadowHost) {
if (!node_1.shadowRoot) {
node_1.attachShadow({ mode: "open" });
} else {
while (node_1.shadowRoot.firstChild) {
node_1.shadowRoot.removeChild(node_1.shadowRoot.firstChild);
}
}
}
return node_1;
}
case NodeType$2.Text:
return doc.createTextNode(n.isStyle && hackCss ? addHoverClass(n.textContent, cache) : n.textContent);
case NodeType$2.CDATA:
return doc.createCDATASection(n.textContent);
case NodeType$2.Comment:
return doc.createComment(n.textContent);
default:
return null;
}
}
function buildNodeWithSN(n, options) {
var doc = options.doc, mirror = options.mirror, _a = options.skipChild, skipChild = _a === void 0 ? false : _a, _b = options.hackCss, hackCss = _b === void 0 ? true : _b, afterAppend = options.afterAppend, cache = options.cache;
var node = buildNode(n, { doc, hackCss, cache });
if (!node) {
return null;
}
if (n.rootId && mirror.getNode(n.rootId) !== doc) {
mirror.replace(n.rootId, doc);
}
if (n.type === NodeType$2.Document) {
doc.close();
doc.open();
if (n.compatMode === "BackCompat" && n.childNodes && n.childNodes[0].type !== NodeType$2.DocumentType) {
if (n.childNodes[0].type === NodeType$2.Element && "xmlns" in n.childNodes[0].attributes && n.childNodes[0].attributes.xmlns === "http://www.w3.org/1999/xhtml") {
doc.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">');
} else {
doc.write('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "">');
}
}
node = doc;
}
mirror.add(node, n);
if ((n.type === NodeType$2.Document || n.type === NodeType$2.Element) && !skipChild) {
for (var _i = 0, _c = n.childNodes; _i < _c.length; _i++) {
var childN = _c[_i];
var childNode = buildNodeWithSN(childN, {
doc,
mirror,
skipChild: false,
hackCss,
afterAppend,
cache
});
if (!childNode) {
console.warn("Failed to rebuild", childN);
continue;
}
if (childN.isShadow && isElement(node) && node.shadowRoot) {
node.shadowRoot.appendChild(childNode);
} else {
node.appendChild(childNode);
}
if (afterAppend) {
afterAppend(childNode, childN.id);
}
}
}
return node;
}
function visit(mirror, onVisit) {
function walk(node) {
onVisit(node);
}
for (var _i = 0, _a = mirror.getIds(); _i < _a.length; _i++) {
var id = _a[_i];
if (mirror.has(id)) {
walk(mirror.getNode(id));
}
}
}
function handleScroll(node, mirror) {
var n = mirror.getMeta(node);
if ((n === null || n === void 0 ? void 0 : n.type) !== NodeType$2.Element) {
return;
}
var el = node;
for (var name_3 in n.attributes) {
if (!(Object.prototype.hasOwnProperty.call(n.attributes, name_3) && name_3.startsWith("rr_"))) {
continue;
}
var value = n.attributes[name_3];
if (name_3 === "rr_scrollLeft") {
el.scrollLeft = value;
}
if (name_3 === "rr_scrollTop") {
el.scrollTop = value;
}
}
}
function rebuild(n, options) {
var doc = options.doc, onVisit = options.onVisit, _a = options.hackCss, hackCss = _a === void 0 ? true : _a, afterAppend = options.afterAppend, cache = options.cache, _b = options.mirror, mirror = _b === void 0 ? new Mirror$2() : _b;
var node = buildNodeWithSN(n, {
doc,
mirror,
skipChild: false,
hackCss,
afterAppend,
cache
});
visit(mirror, function(visitedNode) {
if (onVisit) {
onVisit(visitedNode);
}
handleScroll(visitedNode, mirror);
});
return node;
}
var NodeType$1;
(function(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";
})(NodeType$1 || (NodeType$1 = {}));
var Mirror$1 = function() {
function Mirror2() {
this.idNodeMap = /* @__PURE__ */ new Map();
this.nodeMetaMap = /* @__PURE__ */ new WeakMap();
}
Mirror2.prototype.getId = function(n) {
var _a;
if (!n)
return -1;
var id = (_a = this.getMeta(n)) === null || _a === void 0 ? void 0 : _a.id;
return id !== null && id !== void 0 ? id : -1;
};
Mirror2.prototype.getNode = function(id) {
return this.idNodeMap.get(id) || null;
};
Mirror2.prototype.getIds = function() {
return Array.from(this.idNodeMap.keys());
};
Mirror2.prototype.getMeta = function(n) {
return this.nodeMetaMap.get(n) || null;
};
Mirror2.prototype.removeNodeFromMap = function(n) {
var _this = this;
var id = this.getId(n);
this.idNodeMap["delete"](id);
if (n.childNodes) {
n.childNodes.forEach(function(childNode) {
return _this.removeNodeFromMap(childNode);
});
}
};
Mirror2.prototype.has = function(id) {
return this.idNodeMap.has(id);
};
Mirror2.prototype.hasNode = function(node) {
return this.nodeMetaMap.has(node);
};
Mirror2.prototype.add = function(n, meta) {
var id = meta.id;
this.idNodeMap.set(id, n);
this.nodeMetaMap.set(n, meta);
};
Mirror2.prototype.replace = function(id, n) {
var oldNode = this.getNode(id);
if (oldNode) {
var meta = this.nodeMetaMap.get(oldNode);
if (meta)
this.nodeMetaMap.set(n, meta);
}
this.idNodeMap.set(id, n);
};
Mirror2.prototype.reset = function() {
this.idNodeMap = /* @__PURE__ */ new Map();
this.nodeMetaMap = /* @__PURE__ */ new WeakMap();
};
return Mirror2;
}();
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, (_, c) => c ? c.toUpperCase() : "");
};
const hyphenateRE = /\B([A-Z])/g;
const hyphenate = (str) => {
return str.replace(hyphenateRE, "-$1").toLowerCase();
};
class BaseRRNode {
constructor(..._args) {
this.childNodes = [];
this.parentElement = null;
this.parentNode = null;
this.ELEMENT_NODE = NodeType.ELEMENT_NODE;
this.TEXT_NODE = NodeType.TEXT_NODE;
}
get firstChild() {
return this.childNodes[0] || null;
}
get lastChild() {
return this.childNodes[this.childNodes.length - 1] || null;
}
get nextSibling() {
const parentNode = this.parentNode;
if (!parentNode)
return null;
const siblings = parentNode.childNodes;
const index = siblings.indexOf(this);
return siblings[index + 1] || null;
}
contains(node) {
if (node === this)
return true;
for (const child of this.childNodes) {
if (child.contains(node))
return true;
}
return false;
}
appendChild(_newChild) {
throw new Error(`RRDomException: Failed to execute 'appendChild' on 'RRNode': This RRNode type does not support this method.`);
}
insertBefore(_newChild, _refChild) {
throw new Error(`RRDomException: Failed to execute 'insertBefore' on 'RRNode': This RRNode type does not support this method.`);
}
removeChild(_node) {
throw new Error(`RRDomException: Failed to execute 'removeChild' on 'RRNode': This RRNode type does not support this method.`);
}
toString() {
return "RRNode";
}
}
function BaseRRDocumentImpl(RRNodeClass) {
return class BaseRRDocument extends RRNodeClass {
constructor() {
super(...arguments);
this.nodeType = NodeType.DOCUMENT_NODE;
this.nodeName = "#document";
this.compatMode = "CSS1Compat";
this.RRNodeType = NodeType$1.Document;
this.textContent = null;
}
get documentElement() {
return this.childNodes.find((node) => node.RRNodeType === NodeType$1.Element && node.tagName === "HTML") || null;
}
get body() {
var _a;
return ((_a = this.documentElement) === null || _a === void 0 ? void 0 : _a.childNodes.find((node) => node.RRNodeType === NodeType$1.Element && node.tagName === "BODY")) || null;
}
get head() {
var _a;
return ((_a = this.documentElement) === null || _a === void 0 ? void 0 : _a.childNodes.find((node) => node.RRNodeType === NodeType$1.Element && node.tagName === "HEAD")) || null;
}
get implementation() {
return this;
}
get firstElementChild() {
return this.documentElement;
}
appendChild(childNode) {
const nodeType = childNode.RRNodeType;
if (nodeType === NodeType$1.Element || nodeType === NodeType$1.DocumentType) {
if (this.childNodes.some((s) => s.RRNodeType === nodeType)) {
throw new Error(`RRDomException: Failed to execute 'appendChild' on 'RRNode': Only one ${nodeType === NodeType$1.Element ? "RRElement" : "RRDoctype"} on RRDocument allowed.`);
}
}
childNode.parentElement = null;
childNode.parentNode = this;
this.childNodes.push(childNode);
return childNode;
}
insertBefore(newChild, refChild) {
const nodeType = newChild.RRNodeType;
if (nodeType === NodeType$1.Element || nodeType === NodeType$1.DocumentType) {
if (this.childNodes.some((s) => s.RRNodeType === nodeType)) {
throw new Error(`RRDomException: Failed to execute 'insertBefore' on 'RRNode': Only one ${nodeType === NodeType$1.Element ? "RRElement" : "RRDoctype"} on RRDocument allowed.`);
}
}
if (refChild === null)
return this.appendChild(newChild);
const childIndex = this.childNodes.indexOf(refChild);
if (childIndex == -1)
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.");
this.childNodes.splice(childIndex, 0, newChild);
newChild.parentElement = null;
newChild.parentNode = this;
return newChild;
}
removeChild(node) {
const indexOfChild = this.childNodes.indexOf(node);
if (indexOfChild === -1)
throw new Error("Failed to execute 'removeChild' on 'RRDocument': The RRNode to be removed is not a child of this RRNode.");
this.childNodes.splice(indexOfChild, 1);
node.parentElement = null;
node.parentNode = null;
return node;
}
open() {
this.childNodes = [];
}
close() {
}
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 (BaseRRDocumentTypeImpl(BaseRRNode))(qualifiedName, publicId, systemId);
doctype.ownerDocument = this;
return doctype;
}
createElement(tagName) {
const element = new (BaseRRElementImpl(BaseRRNode))(tagName);
element.ownerDocument = this;
return element;
}
createElementNS(_namespaceURI, qualifiedName) {
return this.createElement(qualifiedName);
}
createTextNode(data) {
const text = new (BaseRRTextImpl(BaseRRNode))(data);
text.ownerDocument = this;
return text;
}
createComment(data) {
const comment = new (BaseRRCommentImpl(BaseRRNode))(data);
comment.ownerDocument = this;
return comment;
}
createCDATASection(data) {
const CDATASection = new (BaseRRCDATASectionImpl(BaseRRNode))(data);
CDATASection.ownerDocument = this;
return CDATASection;
}
toString() {
return "RRDocument";
}
};
}
function BaseRRDocumentTypeImpl(RRNodeClass) {
return class BaseRRDocumentType extends RRNodeClass {
constructor(qualifiedName, publicId, systemId) {
super();
this.nodeType = NodeType.DOCUMENT_TYPE_NODE;
this.RRNodeType = NodeType$1.DocumentType;
this.textContent = null;
this.name = qualifiedName;
this.publicId = publicId;
this.systemId = systemId;
this.nodeName = qualifiedName;
}
toString() {
return "RRDocumentType";
}
};
}
function BaseRRElementImpl(RRNodeClass) {
return class BaseRRElement extends RRNodeClass {
constructor(tagName) {
super();
this.nodeType = NodeType.ELEMENT_NODE;
this.RRNodeType = NodeType$1.Element;
this.attributes = {};
this.shadowRoot = null;
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.childNodes = [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) {
this.childNodes.push(newChild);
newChild.parentNode = this;
newChild.parentElement = this;
return newChild;
}
insertBefore(newChild, refChild) {
if (refChild === null)
return this.appendChild(newChild);
const childIndex = this.childNodes.indexOf(refChild);
if (childIndex == -1)
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.");
this.childNodes.splice(childIndex, 0, newChild);
newChild.parentElement = this;
newChild.parentNode = this;
return newChild;
}
removeChild(node) {
const indexOfChild = this.childNodes.indexOf(node);
if (indexOfChild === -1)
throw new Error("Failed to execute 'removeChild' on 'RRElement': The RRNode to be removed is not a child of this RRNode.");
this.childNodes.splice(indexOfChild, 1);
node.parentElement = null;
node.parentNode = null;
return node;
}
attachShadow(_init) {
const shadowRoot = this.ownerDocument.createElement("SHADOWROOT");
this.shadowRoot = shadowRoot;
return shadowRoot;
}
dispatchEvent(_event) {
return true;
}
toString() {
let attributeString = "";
for (const attribute in this.attributes) {
attributeString += `${attribute}="${this.attributes[attribute]}" `;
}
return `${this.tagName} ${attributeString}`;
}
};
}
function BaseRRMediaElementImpl(RRElementClass) {
return class BaseRRMediaElement extends RRElementClass {
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;
}
};
}
function BaseRRTextImpl(RRNodeClass) {
return class BaseRRText extends RRNodeClass {
constructor(data) {
super();
this.nodeType = NodeType.TEXT_NODE;
this.nodeName = "#text";
this.RRNodeType = NodeType$1.Text;
this.data = data;
}
get textContent() {
return this.data;
}
set textContent(textContent) {
this.data = textContent;
}
toString() {
return `RRText text=${JSON.stringify(this.data)}`;
}
};
}
function BaseRRCommentImpl(RRNodeClass) {
return class BaseRRComment extends RRNodeClass {
constructor(data) {
super();
this.nodeType = NodeType.COMMENT_NODE;
this.nodeName = "#comment";
this.RRNodeType = NodeType$1.Comment;
this.data = data;
}
get textContent() {
return this.data;
}
set textContent(textContent) {
this.data = textContent;
}
toString() {
return `RRComment text=${JSON.stringify(this.data)}`;
}
};
}
function BaseRRCDATASectionImpl(RRNodeClass) {
return class BaseRRCDATASection extends RRNodeClass {
constructor(data) {
super();
this.nodeName = "#cdata-section";
this.nodeType = NodeType.CDATA_SECTION_NODE;
this.RRNodeType = NodeType$1.CDATA;
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) {
this.classes = [];
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(" "));
};
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;
}
}
var NodeType;
(function(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";
})(NodeType || (NodeType = {}));
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"
};
function diff(oldTree, newTree, replayer, rrnodeMirror) {
const oldChildren = oldTree.childNodes;
const newChildren = newTree.childNodes;
rrnodeMirror = rrnodeMirror || newTree.mirror || newTree.ownerDocument.mirror;
if (oldChildren.length > 0 || newChildren.length > 0) {
diffChildren(Array.from(oldChildren), newChildren, oldTree, replayer, rrnodeMirror);
}
let inputDataToApply = null, scrollDataToApply = null;
switch (newTree.RRNodeType) {
case NodeType$1.Document: {
const newRRDocument = newTree;
scrollDataToApply = newRRDocument.scrollData;
break;
}
case NodeType$1.Element: {
const oldElement = oldTree;
const newRRElement = newTree;
diffProps(oldElement, newRRElement, rrnodeMirror);
scrollDataToApply = newRRElement.scrollData;
inputDataToApply = newRRElement.inputData;
switch (newRRElement.tagName) {
case "AUDIO":
case "VIDEO": {
const oldMediaElement = oldTree;
const newMediaRRElement = newRRElement;
if (newMediaRRElement.paused !== void 0)
newMediaRRElement.paused ? void oldMediaElement.pause() : void oldMediaElement.play();
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((canvasMutation) => replayer.applyCanvas(canvasMutation.event, canvasMutation.mutation, oldTree));
}
break;
case "STYLE":
{
const styleSheet = oldElement.sheet;
styleSheet && newTree.rules.forEach((data) => replayer.applyStyleSheetMutation(data, styleSheet));
}
break;
}
if (newRRElement.shadowRoot) {
if (!oldElement.shadowRoot)
oldElement.attachShadow({ mode: "open" });
const oldChildren2 = oldElement.shadowRoot.childNodes;
const newChildren2 = newRRElement.shadowRoot.childNodes;
if (oldChildren2.length > 0 || newChildren2.length > 0)
diffChildren(Array.from(oldChildren2), newChildren2, oldElement.shadowRoot, replayer, r