UNPKG

@amplitude/rrweb-utils

Version:

This package contains the shared utility functions used across rrweb packages. See the [guide](../../guide.md) for more info on rrweb.

168 lines (167 loc) 5.32 kB
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 = {}; function angularZoneUnpatchedAlternative(key) { var _a, _b; const angularUnpatchedVersionSymbol = (_b = (_a = globalThis == null ? void 0 : globalThis.Zone) == null ? void 0 : _a.__symbol__) == null ? void 0 : _b.call(_a, key); if (angularUnpatchedVersionSymbol && globalThis[angularUnpatchedVersionSymbol]) { return globalThis[angularUnpatchedVersionSymbol]; } else { return void 0; } } function getUntaintedPrototype(key) { if (untaintedBasePrototype[key]) return untaintedBasePrototype[key]; const candidate = angularZoneUnpatchedAlternative(key) || globalThis[key]; const defaultPrototype = candidate.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) { untaintedBasePrototype[key] = candidate.prototype; return candidate.prototype; } try { const iframeEl = document.createElement("iframe"); document.body.appendChild(iframeEl); const win = iframeEl.contentWindow; if (!win) return candidate.prototype; const untaintedObject = win[key].prototype; document.body.removeChild(iframeEl); if (!untaintedObject) return defaultPrototype; return untaintedBasePrototype[key] = untaintedObject; } catch { 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; } const index = { childNodes, parentNode, parentElement, textContent, contains, getRootNode, host, styleSheets, shadowRoot, querySelector, querySelectorAll, mutationObserver: mutationObserverCtor }; export { childNodes, contains, index as default, getRootNode, getUntaintedAccessor, getUntaintedMethod, getUntaintedPrototype, host, mutationObserverCtor, parentElement, parentNode, querySelector, querySelectorAll, shadowRoot, styleSheets, textContent }; //# sourceMappingURL=rrweb-utils.js.map