@appsurify-testmap/rrweb-utils
Version:
This package contains the shared utility functions used across rrweb packages. See the [guide](../../guide.md) for more info on rrweb.
272 lines (271 loc) • 9.31 kB
JavaScript
(function (g, f) {if ("object" == typeof exports && "object" == typeof module) {module.exports = f();} else if ("function" == typeof define && define.amd) {define("rrwebUtils", [], f);} else if ("object" == typeof exports) {exports["rrwebUtils"] = f();} else {g["rrwebUtils"] = f();}}(typeof self !== 'undefined' ? self : typeof globalThis !== 'undefined' ? globalThis : this, () => {var exports = {};var module = { exports };
;
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const testableAccessors = {
Node: ["childNodes", "parentNode", "parentElement", "textContent"],
ShadowRoot: ["host", "styleSheets"],
Element: ["shadowRoot", "querySelector", "querySelectorAll"],
MutationObserver: []
};
const testableMethods = {
Node: ["contains", "getRootNode"],
ShadowRoot: ["getSelection"],
Element: [],
MutationObserver: ["constructor"]
};
const untaintedBasePrototype = {};
const isAngularZonePresent = () => {
return !!globalThis.Zone;
};
function getUntaintedPrototype(key) {
if (untaintedBasePrototype[key])
return untaintedBasePrototype[key];
const defaultObj = globalThis[key];
const defaultPrototype = defaultObj.prototype;
const accessorNames = key in testableAccessors ? testableAccessors[key] : void 0;
const isUntaintedAccessors = Boolean(
accessorNames && // @ts-expect-error 2345
accessorNames.every(
(accessor) => {
var _a, _b;
return Boolean(
(_b = (_a = Object.getOwnPropertyDescriptor(defaultPrototype, accessor)) == null ? void 0 : _a.get) == null ? void 0 : _b.toString().includes("[native code]")
);
}
)
);
const methodNames = key in testableMethods ? testableMethods[key] : void 0;
const isUntaintedMethods = Boolean(
methodNames && methodNames.every(
// @ts-expect-error 2345
(method) => {
var _a;
return typeof defaultPrototype[method] === "function" && ((_a = defaultPrototype[method]) == null ? void 0 : _a.toString().includes("[native code]"));
}
)
);
if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {
untaintedBasePrototype[key] = defaultObj.prototype;
return defaultObj.prototype;
}
try {
const iframeEl = document.createElement("iframe");
document.body.appendChild(iframeEl);
const win = iframeEl.contentWindow;
if (!win)
return defaultObj.prototype;
const untaintedObject = win[key].prototype;
document.body.removeChild(iframeEl);
if (!untaintedObject)
return defaultPrototype;
return untaintedBasePrototype[key] = untaintedObject;
} catch (e) {
return defaultPrototype;
}
}
const untaintedAccessorCache = {};
function getUntaintedAccessor(key, instance, accessor) {
var _a;
const cacheKey = `${key}.${String(accessor)}`;
if (untaintedAccessorCache[cacheKey])
return untaintedAccessorCache[cacheKey].call(
instance
);
const untaintedPrototype = getUntaintedPrototype(key);
const untaintedAccessor = (_a = Object.getOwnPropertyDescriptor(
untaintedPrototype,
accessor
)) == null ? void 0 : _a.get;
if (!untaintedAccessor)
return instance[accessor];
untaintedAccessorCache[cacheKey] = untaintedAccessor;
return untaintedAccessor.call(instance);
}
const untaintedMethodCache = {};
function getUntaintedMethod(key, instance, method) {
const cacheKey = `${key}.${String(method)}`;
if (untaintedMethodCache[cacheKey])
return untaintedMethodCache[cacheKey].bind(
instance
);
const untaintedPrototype = getUntaintedPrototype(key);
const untaintedMethod = untaintedPrototype[method];
if (typeof untaintedMethod !== "function")
return instance[method];
untaintedMethodCache[cacheKey] = untaintedMethod;
return untaintedMethod.bind(instance);
}
function childNodes(n) {
return getUntaintedAccessor("Node", n, "childNodes");
}
function parentNode(n) {
return getUntaintedAccessor("Node", n, "parentNode");
}
function parentElement(n) {
return getUntaintedAccessor("Node", n, "parentElement");
}
function textContent(n) {
return getUntaintedAccessor("Node", n, "textContent");
}
function contains(n, other) {
return getUntaintedMethod("Node", n, "contains")(other);
}
function getRootNode(n) {
return getUntaintedMethod("Node", n, "getRootNode")();
}
function host(n) {
if (!n || !("host" in n))
return null;
return getUntaintedAccessor("ShadowRoot", n, "host");
}
function styleSheets(n) {
return n.styleSheets;
}
function shadowRoot(n) {
if (!n || !("shadowRoot" in n))
return null;
return getUntaintedAccessor("Element", n, "shadowRoot");
}
function querySelector(n, selectors) {
return getUntaintedAccessor("Element", n, "querySelector")(selectors);
}
function querySelectorAll(n, selectors) {
return getUntaintedAccessor("Element", n, "querySelectorAll")(selectors);
}
function mutationObserverCtor() {
return getUntaintedPrototype("MutationObserver").constructor;
}
function patch(source, name, replacement) {
try {
if (!(name in source)) {
return () => {
};
}
const original = source[name];
const wrapped = replacement(original);
if (typeof wrapped === "function") {
wrapped.prototype = wrapped.prototype || {};
Object.defineProperties(wrapped, {
__rrweb_original__: {
enumerable: false,
value: original
}
});
}
source[name] = wrapped;
return () => {
source[name] = original;
};
} catch (e) {
return () => {
};
}
}
function describeNode(el) {
const tag = el.tagName.toLowerCase();
const id = el.id ? `#${el.id}` : "";
const classes = el.classList.length ? "." + Array.from(el.classList).join(".") : "";
return `${tag}${id}${classes}`;
}
function isAncestorOpacityVisible(el, win) {
var _a;
let node = el.parentElement;
while (node) {
const s = (_a = win.getComputedStyle) == null ? void 0 : _a.call(win, node);
if (s && (parseFloat(s.opacity) || 0) <= 0) {
return false;
}
node = node.parentElement;
}
return true;
}
function getElementVisibility(el) {
var _a2;
var _a, _b;
const win = (_a2 = (_a = el.ownerDocument) == null ? void 0 : _a.defaultView) != null ? _a2 : window;
const rect = el.getBoundingClientRect();
const viewportWidth = win.innerWidth || win.document.documentElement.clientWidth || 0;
const viewportHeight = win.innerHeight || win.document.documentElement.clientHeight || 0;
const elHasSize = rect.width > 0 && rect.height > 0;
const isViewportVisible = elHasSize && rect.bottom > 0 && rect.right > 0 && rect.top < viewportHeight && rect.left < viewportWidth;
const style = (_b = win.getComputedStyle) == null ? void 0 : _b.call(win, el);
const isOwnStyleVisible = !!style && style.display !== "none" && style.visibility !== "hidden" && (parseFloat(style.opacity) || 0) > 0;
const isCSSVisible = isOwnStyleVisible && isAncestorOpacityVisible(el, win);
const isVisible = isCSSVisible && isViewportVisible;
let ratio = 0;
if (isVisible) {
const xOverlap = Math.max(
0,
Math.min(rect.right, viewportWidth) - Math.max(rect.left, 0)
);
const yOverlap = Math.max(
0,
Math.min(rect.bottom, viewportHeight) - Math.max(rect.top, 0)
);
const intersectionArea = xOverlap * yOverlap;
const elementArea = rect.width * rect.height;
ratio = elementArea > 0 ? intersectionArea / elementArea : 0;
}
return {
isVisible,
isCSSVisible,
isViewportVisible,
hasSize: elHasSize,
ratio
};
}
const index = {
childNodes,
parentNode,
parentElement,
textContent,
contains,
getRootNode,
host,
styleSheets,
shadowRoot,
querySelector,
querySelectorAll,
mutationObserver: mutationObserverCtor,
patch,
describeNode,
getElementVisibility
};
exports.childNodes = childNodes;
exports.contains = contains;
exports.default = index;
exports.describeNode = describeNode;
exports.getElementVisibility = getElementVisibility;
exports.getRootNode = getRootNode;
exports.getUntaintedAccessor = getUntaintedAccessor;
exports.getUntaintedMethod = getUntaintedMethod;
exports.getUntaintedPrototype = getUntaintedPrototype;
exports.host = host;
exports.isAngularZonePresent = isAngularZonePresent;
exports.mutationObserverCtor = mutationObserverCtor;
exports.parentElement = parentElement;
exports.parentNode = parentNode;
exports.patch = patch;
exports.querySelector = querySelector;
exports.querySelectorAll = querySelectorAll;
exports.shadowRoot = shadowRoot;
exports.styleSheets = styleSheets;
exports.textContent = textContent;
;if (typeof module.exports == "object" && typeof exports == "object") {
var __cp = (to, from, except, desc) => {
if ((from && typeof from === "object") || typeof from === "function") {
for (let key of Object.getOwnPropertyNames(from)) {
if (!Object.prototype.hasOwnProperty.call(to, key) && key !== except)
Object.defineProperty(to, key, {
get: () => from[key],
enumerable: !(desc = Object.getOwnPropertyDescriptor(from, key)) || desc.enumerable,
});
}
}
return to;
};
module.exports = __cp(module.exports, exports);
}
return module.exports;
}))
//# sourceMappingURL=rrweb-utils.umd.cjs.map