@appsurify-testmap/rrweb-utils 2.0.0-alpha.40 → 2.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -22,6 +22,7 @@ declare const _default: {
22
22
  querySelector: typeof querySelector;
23
23
  querySelectorAll: typeof querySelectorAll;
24
24
  mutationObserver: typeof mutationObserverCtor;
25
+ patch: typeof patch;
25
26
  };
26
27
  export default _default;
27
28
 
@@ -43,6 +44,10 @@ export declare function parentElement(n: Node): HTMLElement | null;
43
44
 
44
45
  export declare function parentNode(n: Node): ParentNode | null;
45
46
 
47
+ export declare function patch(source: {
48
+ [key: string]: any;
49
+ }, name: string, replacement: (...args: unknown[]) => unknown): () => void;
50
+
46
51
  export declare function querySelector(n: Element, selectors: string): Element | null;
47
52
 
48
53
  export declare function querySelectorAll(n: Element, selectors: string): NodeListOf<Element>;
package/dist/index.d.ts CHANGED
@@ -22,6 +22,7 @@ declare const _default: {
22
22
  querySelector: typeof querySelector;
23
23
  querySelectorAll: typeof querySelectorAll;
24
24
  mutationObserver: typeof mutationObserverCtor;
25
+ patch: typeof patch;
25
26
  };
26
27
  export default _default;
27
28
 
@@ -43,6 +44,10 @@ export declare function parentElement(n: Node): HTMLElement | null;
43
44
 
44
45
  export declare function parentNode(n: Node): ParentNode | null;
45
46
 
47
+ export declare function patch(source: {
48
+ [key: string]: any;
49
+ }, name: string, replacement: (...args: unknown[]) => unknown): () => void;
50
+
46
51
  export declare function querySelector(n: Element, selectors: string): Element | null;
47
52
 
48
53
  export declare function querySelectorAll(n: Element, selectors: string): NodeListOf<Element>;
@@ -128,6 +128,32 @@ function querySelectorAll(n, selectors) {
128
128
  function mutationObserverCtor() {
129
129
  return getUntaintedPrototype("MutationObserver").constructor;
130
130
  }
131
+ function patch(source, name, replacement) {
132
+ try {
133
+ if (!(name in source)) {
134
+ return () => {
135
+ };
136
+ }
137
+ const original = source[name];
138
+ const wrapped = replacement(original);
139
+ if (typeof wrapped === "function") {
140
+ wrapped.prototype = wrapped.prototype || {};
141
+ Object.defineProperties(wrapped, {
142
+ __rrweb_original__: {
143
+ enumerable: false,
144
+ value: original
145
+ }
146
+ });
147
+ }
148
+ source[name] = wrapped;
149
+ return () => {
150
+ source[name] = original;
151
+ };
152
+ } catch {
153
+ return () => {
154
+ };
155
+ }
156
+ }
131
157
  const index = {
132
158
  childNodes,
133
159
  parentNode,
@@ -140,7 +166,8 @@ const index = {
140
166
  shadowRoot,
141
167
  querySelector,
142
168
  querySelectorAll,
143
- mutationObserver: mutationObserverCtor
169
+ mutationObserver: mutationObserverCtor,
170
+ patch
144
171
  };
145
172
  exports.childNodes = childNodes;
146
173
  exports.contains = contains;
@@ -154,6 +181,7 @@ exports.isAngularZonePresent = isAngularZonePresent;
154
181
  exports.mutationObserverCtor = mutationObserverCtor;
155
182
  exports.parentElement = parentElement;
156
183
  exports.parentNode = parentNode;
184
+ exports.patch = patch;
157
185
  exports.querySelector = querySelector;
158
186
  exports.querySelectorAll = querySelectorAll;
159
187
  exports.shadowRoot = shadowRoot;
@@ -1 +1 @@
1
- {"version":3,"file":"rrweb-utils.cjs","sources":["../src/index.ts"],"sourcesContent":["type PrototypeOwner = Node | ShadowRoot | MutationObserver | Element;\ntype TypeofPrototypeOwner =\n | typeof Node\n | typeof ShadowRoot\n | typeof MutationObserver\n | typeof Element;\n\ntype BasePrototypeCache = {\n Node: typeof Node.prototype;\n ShadowRoot: typeof ShadowRoot.prototype;\n MutationObserver: typeof MutationObserver.prototype;\n Element: typeof Element.prototype;\n};\n\nconst testableAccessors = {\n Node: ['childNodes', 'parentNode', 'parentElement', 'textContent'] as const,\n ShadowRoot: ['host', 'styleSheets'] as const,\n Element: ['shadowRoot', 'querySelector', 'querySelectorAll'] as const,\n MutationObserver: [] as const,\n} as const;\n\nconst testableMethods = {\n Node: ['contains', 'getRootNode'] as const,\n ShadowRoot: ['getSelection'],\n Element: [],\n MutationObserver: ['constructor'],\n} as const;\n\nconst untaintedBasePrototype: Partial<BasePrototypeCache> = {};\n\n/*\n When angular patches things - particularly the MutationObserver -\n they pass the `isNativeFunction` check\n That then causes performance issues\n because Angular's change detection\n doesn't like sharing a mutation observer\n Checking for the presence of the Zone object\n on global is a good-enough proxy for Angular\n to cover most cases\n (you can configure zone.js to have a different name\n on the global object and should then manually run rrweb\n outside the Zone)\n */\nexport const isAngularZonePresent = (): boolean => {\n return !!(globalThis as { Zone?: unknown }).Zone;\n};\n\nexport function getUntaintedPrototype<T extends keyof BasePrototypeCache>(\n key: T,\n): BasePrototypeCache[T] {\n if (untaintedBasePrototype[key])\n return untaintedBasePrototype[key] as BasePrototypeCache[T];\n\n const defaultObj = globalThis[key] as TypeofPrototypeOwner;\n const defaultPrototype = defaultObj.prototype as BasePrototypeCache[T];\n\n // use list of testable accessors to check if the prototype is tainted\n const accessorNames =\n key in testableAccessors ? testableAccessors[key] : undefined;\n const isUntaintedAccessors = Boolean(\n accessorNames &&\n // @ts-expect-error 2345\n accessorNames.every((accessor: keyof typeof defaultPrototype) =>\n Boolean(\n Object.getOwnPropertyDescriptor(defaultPrototype, accessor)\n ?.get?.toString()\n .includes('[native code]'),\n ),\n ),\n );\n\n const methodNames = key in testableMethods ? testableMethods[key] : undefined;\n const isUntaintedMethods = Boolean(\n methodNames &&\n methodNames.every(\n // @ts-expect-error 2345\n (method: keyof typeof defaultPrototype) =>\n typeof defaultPrototype[method] === 'function' &&\n defaultPrototype[method]?.toString().includes('[native code]'),\n ),\n );\n\n if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {\n untaintedBasePrototype[key] = defaultObj.prototype as BasePrototypeCache[T];\n return defaultObj.prototype as BasePrototypeCache[T];\n }\n\n try {\n const iframeEl = document.createElement('iframe');\n document.body.appendChild(iframeEl);\n const win = iframeEl.contentWindow;\n if (!win) return defaultObj.prototype as BasePrototypeCache[T];\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n const untaintedObject = (win as any)[key]\n .prototype as BasePrototypeCache[T];\n // cleanup\n document.body.removeChild(iframeEl);\n\n if (!untaintedObject) return defaultPrototype;\n\n return (untaintedBasePrototype[key] = untaintedObject);\n } catch {\n return defaultPrototype;\n }\n}\n\nconst untaintedAccessorCache: Record<\n string,\n (this: PrototypeOwner, ...args: unknown[]) => unknown\n> = {};\n\nexport function getUntaintedAccessor<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n accessor: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(accessor)}`;\n if (untaintedAccessorCache[cacheKey])\n return untaintedAccessorCache[cacheKey].call(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const untaintedAccessor = Object.getOwnPropertyDescriptor(\n untaintedPrototype,\n accessor,\n )?.get;\n\n if (!untaintedAccessor) return instance[accessor];\n\n untaintedAccessorCache[cacheKey] = untaintedAccessor;\n\n return untaintedAccessor.call(instance) as BasePrototypeCache[K][T];\n}\n\ntype BaseMethod<K extends keyof BasePrototypeCache> = (\n this: BasePrototypeCache[K],\n ...args: unknown[]\n) => unknown;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst untaintedMethodCache: Record<string, BaseMethod<any>> = {};\nexport function getUntaintedMethod<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n method: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(method)}`;\n if (untaintedMethodCache[cacheKey])\n return untaintedMethodCache[cacheKey].bind(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n const untaintedMethod = untaintedPrototype[method];\n\n if (typeof untaintedMethod !== 'function') return instance[method];\n\n untaintedMethodCache[cacheKey] = untaintedMethod as BaseMethod<K>;\n\n return untaintedMethod.bind(instance) as BasePrototypeCache[K][T];\n}\n\nexport function childNodes(n: Node): NodeListOf<Node> {\n return getUntaintedAccessor('Node', n, 'childNodes');\n}\n\nexport function parentNode(n: Node): ParentNode | null {\n return getUntaintedAccessor('Node', n, 'parentNode');\n}\n\nexport function parentElement(n: Node): HTMLElement | null {\n return getUntaintedAccessor('Node', n, 'parentElement');\n}\n\nexport function textContent(n: Node): string | null {\n return getUntaintedAccessor('Node', n, 'textContent');\n}\n\nexport function contains(n: Node, other: Node): boolean {\n return getUntaintedMethod('Node', n, 'contains')(other);\n}\n\nexport function getRootNode(n: Node): Node {\n return getUntaintedMethod('Node', n, 'getRootNode')();\n}\n\nexport function host(n: ShadowRoot): Element | null {\n if (!n || !('host' in n)) return null;\n return getUntaintedAccessor('ShadowRoot', n, 'host');\n}\n\nexport function styleSheets(n: ShadowRoot): StyleSheetList {\n return n.styleSheets;\n}\n\nexport function shadowRoot(n: Node): ShadowRoot | null {\n if (!n || !('shadowRoot' in n)) return null;\n return getUntaintedAccessor('Element', n as Element, 'shadowRoot');\n}\n\nexport function querySelector(n: Element, selectors: string): Element | null {\n return getUntaintedAccessor('Element', n, 'querySelector')(selectors);\n}\n\nexport function querySelectorAll(\n n: Element,\n selectors: string,\n): NodeListOf<Element> {\n return getUntaintedAccessor('Element', n, 'querySelectorAll')(selectors);\n}\n\nexport function mutationObserverCtor(): (typeof MutationObserver)['prototype']['constructor'] {\n return getUntaintedPrototype('MutationObserver').constructor;\n}\n\nexport default {\n childNodes,\n parentNode,\n parentElement,\n textContent,\n contains,\n getRootNode,\n host,\n styleSheets,\n shadowRoot,\n querySelector,\n querySelectorAll,\n mutationObserver: mutationObserverCtor,\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rrweb-utils.cjs","sources":["../src/index.ts"],"sourcesContent":["type PrototypeOwner = Node | ShadowRoot | MutationObserver | Element;\ntype TypeofPrototypeOwner =\n | typeof Node\n | typeof ShadowRoot\n | typeof MutationObserver\n | typeof Element;\n\ntype BasePrototypeCache = {\n Node: typeof Node.prototype;\n ShadowRoot: typeof ShadowRoot.prototype;\n MutationObserver: typeof MutationObserver.prototype;\n Element: typeof Element.prototype;\n};\n\nconst testableAccessors = {\n Node: ['childNodes', 'parentNode', 'parentElement', 'textContent'] as const,\n ShadowRoot: ['host', 'styleSheets'] as const,\n Element: ['shadowRoot', 'querySelector', 'querySelectorAll'] as const,\n MutationObserver: [] as const,\n} as const;\n\nconst testableMethods = {\n Node: ['contains', 'getRootNode'] as const,\n ShadowRoot: ['getSelection'],\n Element: [],\n MutationObserver: ['constructor'],\n} as const;\n\nconst untaintedBasePrototype: Partial<BasePrototypeCache> = {};\n\n/*\n When angular patches things - particularly the MutationObserver -\n they pass the `isNativeFunction` check\n That then causes performance issues\n because Angular's change detection\n doesn't like sharing a mutation observer\n Checking for the presence of the Zone object\n on global is a good-enough proxy for Angular\n to cover most cases\n (you can configure zone.js to have a different name\n on the global object and should then manually run rrweb\n outside the Zone)\n */\nexport const isAngularZonePresent = (): boolean => {\n return !!(globalThis as { Zone?: unknown }).Zone;\n};\n\nexport function getUntaintedPrototype<T extends keyof BasePrototypeCache>(\n key: T,\n): BasePrototypeCache[T] {\n if (untaintedBasePrototype[key])\n return untaintedBasePrototype[key] as BasePrototypeCache[T];\n\n const defaultObj = globalThis[key] as TypeofPrototypeOwner;\n const defaultPrototype = defaultObj.prototype as BasePrototypeCache[T];\n\n // use list of testable accessors to check if the prototype is tainted\n const accessorNames =\n key in testableAccessors ? testableAccessors[key] : undefined;\n const isUntaintedAccessors = Boolean(\n accessorNames &&\n // @ts-expect-error 2345\n accessorNames.every((accessor: keyof typeof defaultPrototype) =>\n Boolean(\n Object.getOwnPropertyDescriptor(defaultPrototype, accessor)\n ?.get?.toString()\n .includes('[native code]'),\n ),\n ),\n );\n\n const methodNames = key in testableMethods ? testableMethods[key] : undefined;\n const isUntaintedMethods = Boolean(\n methodNames &&\n methodNames.every(\n // @ts-expect-error 2345\n (method: keyof typeof defaultPrototype) =>\n typeof defaultPrototype[method] === 'function' &&\n defaultPrototype[method]?.toString().includes('[native code]'),\n ),\n );\n\n if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {\n untaintedBasePrototype[key] = defaultObj.prototype as BasePrototypeCache[T];\n return defaultObj.prototype as BasePrototypeCache[T];\n }\n\n try {\n const iframeEl = document.createElement('iframe');\n document.body.appendChild(iframeEl);\n const win = iframeEl.contentWindow;\n if (!win) return defaultObj.prototype as BasePrototypeCache[T];\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n const untaintedObject = (win as any)[key]\n .prototype as BasePrototypeCache[T];\n // cleanup\n document.body.removeChild(iframeEl);\n\n if (!untaintedObject) return defaultPrototype;\n\n return (untaintedBasePrototype[key] = untaintedObject);\n } catch {\n return defaultPrototype;\n }\n}\n\nconst untaintedAccessorCache: Record<\n string,\n (this: PrototypeOwner, ...args: unknown[]) => unknown\n> = {};\n\nexport function getUntaintedAccessor<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n accessor: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(accessor)}`;\n if (untaintedAccessorCache[cacheKey])\n return untaintedAccessorCache[cacheKey].call(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const untaintedAccessor = Object.getOwnPropertyDescriptor(\n untaintedPrototype,\n accessor,\n )?.get;\n\n if (!untaintedAccessor) return instance[accessor];\n\n untaintedAccessorCache[cacheKey] = untaintedAccessor;\n\n return untaintedAccessor.call(instance) as BasePrototypeCache[K][T];\n}\n\ntype BaseMethod<K extends keyof BasePrototypeCache> = (\n this: BasePrototypeCache[K],\n ...args: unknown[]\n) => unknown;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst untaintedMethodCache: Record<string, BaseMethod<any>> = {};\nexport function getUntaintedMethod<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n method: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(method)}`;\n if (untaintedMethodCache[cacheKey])\n return untaintedMethodCache[cacheKey].bind(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n const untaintedMethod = untaintedPrototype[method];\n\n if (typeof untaintedMethod !== 'function') return instance[method];\n\n untaintedMethodCache[cacheKey] = untaintedMethod as BaseMethod<K>;\n\n return untaintedMethod.bind(instance) as BasePrototypeCache[K][T];\n}\n\nexport function childNodes(n: Node): NodeListOf<Node> {\n return getUntaintedAccessor('Node', n, 'childNodes');\n}\n\nexport function parentNode(n: Node): ParentNode | null {\n return getUntaintedAccessor('Node', n, 'parentNode');\n}\n\nexport function parentElement(n: Node): HTMLElement | null {\n return getUntaintedAccessor('Node', n, 'parentElement');\n}\n\nexport function textContent(n: Node): string | null {\n return getUntaintedAccessor('Node', n, 'textContent');\n}\n\nexport function contains(n: Node, other: Node): boolean {\n return getUntaintedMethod('Node', n, 'contains')(other);\n}\n\nexport function getRootNode(n: Node): Node {\n return getUntaintedMethod('Node', n, 'getRootNode')();\n}\n\nexport function host(n: ShadowRoot): Element | null {\n if (!n || !('host' in n)) return null;\n return getUntaintedAccessor('ShadowRoot', n, 'host');\n}\n\nexport function styleSheets(n: ShadowRoot): StyleSheetList {\n return n.styleSheets;\n}\n\nexport function shadowRoot(n: Node): ShadowRoot | null {\n if (!n || !('shadowRoot' in n)) return null;\n return getUntaintedAccessor('Element', n as Element, 'shadowRoot');\n}\n\nexport function querySelector(n: Element, selectors: string): Element | null {\n return getUntaintedAccessor('Element', n, 'querySelector')(selectors);\n}\n\nexport function querySelectorAll(\n n: Element,\n selectors: string,\n): NodeListOf<Element> {\n return getUntaintedAccessor('Element', n, 'querySelectorAll')(selectors);\n}\n\nexport function mutationObserverCtor(): (typeof MutationObserver)['prototype']['constructor'] {\n return getUntaintedPrototype('MutationObserver').constructor;\n}\n\n// copy from https://github.com/getsentry/sentry-javascript/blob/b2109071975af8bf0316d3b5b38f519bdaf5dc15/packages/utils/src/object.ts\nexport function patch(\n source: { [key: string]: any },\n name: string,\n replacement: (...args: unknown[]) => unknown,\n): () => void {\n try {\n if (!(name in source)) {\n return () => {\n //\n };\n }\n\n const original = source[name] as () => unknown;\n const wrapped = replacement(original);\n\n // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work\n // otherwise it'll throw \"TypeError: Object.defineProperties called on non-object\"\n if (typeof wrapped === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n wrapped.prototype = wrapped.prototype || {};\n Object.defineProperties(wrapped, {\n __rrweb_original__: {\n enumerable: false,\n value: original,\n },\n });\n }\n\n source[name] = wrapped;\n\n return () => {\n source[name] = original;\n };\n } catch {\n return () => {\n //\n };\n // This can throw if multiple fill happens on a global object like XMLHttpRequest\n // Fixes https://github.com/getsentry/sentry-javascript/issues/2043\n }\n}\n\nexport default {\n childNodes,\n parentNode,\n parentElement,\n textContent,\n contains,\n getRootNode,\n host,\n styleSheets,\n shadowRoot,\n querySelector,\n querySelectorAll,\n mutationObserver: mutationObserverCtor,\n patch,\n};\n"],"names":[],"mappings":"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"}
@@ -126,6 +126,32 @@ function querySelectorAll(n, selectors) {
126
126
  function mutationObserverCtor() {
127
127
  return getUntaintedPrototype("MutationObserver").constructor;
128
128
  }
129
+ function patch(source, name, replacement) {
130
+ try {
131
+ if (!(name in source)) {
132
+ return () => {
133
+ };
134
+ }
135
+ const original = source[name];
136
+ const wrapped = replacement(original);
137
+ if (typeof wrapped === "function") {
138
+ wrapped.prototype = wrapped.prototype || {};
139
+ Object.defineProperties(wrapped, {
140
+ __rrweb_original__: {
141
+ enumerable: false,
142
+ value: original
143
+ }
144
+ });
145
+ }
146
+ source[name] = wrapped;
147
+ return () => {
148
+ source[name] = original;
149
+ };
150
+ } catch {
151
+ return () => {
152
+ };
153
+ }
154
+ }
129
155
  const index = {
130
156
  childNodes,
131
157
  parentNode,
@@ -138,7 +164,8 @@ const index = {
138
164
  shadowRoot,
139
165
  querySelector,
140
166
  querySelectorAll,
141
- mutationObserver: mutationObserverCtor
167
+ mutationObserver: mutationObserverCtor,
168
+ patch
142
169
  };
143
170
  export {
144
171
  childNodes,
@@ -153,6 +180,7 @@ export {
153
180
  mutationObserverCtor,
154
181
  parentElement,
155
182
  parentNode,
183
+ patch,
156
184
  querySelector,
157
185
  querySelectorAll,
158
186
  shadowRoot,
@@ -1 +1 @@
1
- {"version":3,"file":"rrweb-utils.js","sources":["../src/index.ts"],"sourcesContent":["type PrototypeOwner = Node | ShadowRoot | MutationObserver | Element;\ntype TypeofPrototypeOwner =\n | typeof Node\n | typeof ShadowRoot\n | typeof MutationObserver\n | typeof Element;\n\ntype BasePrototypeCache = {\n Node: typeof Node.prototype;\n ShadowRoot: typeof ShadowRoot.prototype;\n MutationObserver: typeof MutationObserver.prototype;\n Element: typeof Element.prototype;\n};\n\nconst testableAccessors = {\n Node: ['childNodes', 'parentNode', 'parentElement', 'textContent'] as const,\n ShadowRoot: ['host', 'styleSheets'] as const,\n Element: ['shadowRoot', 'querySelector', 'querySelectorAll'] as const,\n MutationObserver: [] as const,\n} as const;\n\nconst testableMethods = {\n Node: ['contains', 'getRootNode'] as const,\n ShadowRoot: ['getSelection'],\n Element: [],\n MutationObserver: ['constructor'],\n} as const;\n\nconst untaintedBasePrototype: Partial<BasePrototypeCache> = {};\n\n/*\n When angular patches things - particularly the MutationObserver -\n they pass the `isNativeFunction` check\n That then causes performance issues\n because Angular's change detection\n doesn't like sharing a mutation observer\n Checking for the presence of the Zone object\n on global is a good-enough proxy for Angular\n to cover most cases\n (you can configure zone.js to have a different name\n on the global object and should then manually run rrweb\n outside the Zone)\n */\nexport const isAngularZonePresent = (): boolean => {\n return !!(globalThis as { Zone?: unknown }).Zone;\n};\n\nexport function getUntaintedPrototype<T extends keyof BasePrototypeCache>(\n key: T,\n): BasePrototypeCache[T] {\n if (untaintedBasePrototype[key])\n return untaintedBasePrototype[key] as BasePrototypeCache[T];\n\n const defaultObj = globalThis[key] as TypeofPrototypeOwner;\n const defaultPrototype = defaultObj.prototype as BasePrototypeCache[T];\n\n // use list of testable accessors to check if the prototype is tainted\n const accessorNames =\n key in testableAccessors ? testableAccessors[key] : undefined;\n const isUntaintedAccessors = Boolean(\n accessorNames &&\n // @ts-expect-error 2345\n accessorNames.every((accessor: keyof typeof defaultPrototype) =>\n Boolean(\n Object.getOwnPropertyDescriptor(defaultPrototype, accessor)\n ?.get?.toString()\n .includes('[native code]'),\n ),\n ),\n );\n\n const methodNames = key in testableMethods ? testableMethods[key] : undefined;\n const isUntaintedMethods = Boolean(\n methodNames &&\n methodNames.every(\n // @ts-expect-error 2345\n (method: keyof typeof defaultPrototype) =>\n typeof defaultPrototype[method] === 'function' &&\n defaultPrototype[method]?.toString().includes('[native code]'),\n ),\n );\n\n if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {\n untaintedBasePrototype[key] = defaultObj.prototype as BasePrototypeCache[T];\n return defaultObj.prototype as BasePrototypeCache[T];\n }\n\n try {\n const iframeEl = document.createElement('iframe');\n document.body.appendChild(iframeEl);\n const win = iframeEl.contentWindow;\n if (!win) return defaultObj.prototype as BasePrototypeCache[T];\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n const untaintedObject = (win as any)[key]\n .prototype as BasePrototypeCache[T];\n // cleanup\n document.body.removeChild(iframeEl);\n\n if (!untaintedObject) return defaultPrototype;\n\n return (untaintedBasePrototype[key] = untaintedObject);\n } catch {\n return defaultPrototype;\n }\n}\n\nconst untaintedAccessorCache: Record<\n string,\n (this: PrototypeOwner, ...args: unknown[]) => unknown\n> = {};\n\nexport function getUntaintedAccessor<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n accessor: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(accessor)}`;\n if (untaintedAccessorCache[cacheKey])\n return untaintedAccessorCache[cacheKey].call(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const untaintedAccessor = Object.getOwnPropertyDescriptor(\n untaintedPrototype,\n accessor,\n )?.get;\n\n if (!untaintedAccessor) return instance[accessor];\n\n untaintedAccessorCache[cacheKey] = untaintedAccessor;\n\n return untaintedAccessor.call(instance) as BasePrototypeCache[K][T];\n}\n\ntype BaseMethod<K extends keyof BasePrototypeCache> = (\n this: BasePrototypeCache[K],\n ...args: unknown[]\n) => unknown;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst untaintedMethodCache: Record<string, BaseMethod<any>> = {};\nexport function getUntaintedMethod<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n method: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(method)}`;\n if (untaintedMethodCache[cacheKey])\n return untaintedMethodCache[cacheKey].bind(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n const untaintedMethod = untaintedPrototype[method];\n\n if (typeof untaintedMethod !== 'function') return instance[method];\n\n untaintedMethodCache[cacheKey] = untaintedMethod as BaseMethod<K>;\n\n return untaintedMethod.bind(instance) as BasePrototypeCache[K][T];\n}\n\nexport function childNodes(n: Node): NodeListOf<Node> {\n return getUntaintedAccessor('Node', n, 'childNodes');\n}\n\nexport function parentNode(n: Node): ParentNode | null {\n return getUntaintedAccessor('Node', n, 'parentNode');\n}\n\nexport function parentElement(n: Node): HTMLElement | null {\n return getUntaintedAccessor('Node', n, 'parentElement');\n}\n\nexport function textContent(n: Node): string | null {\n return getUntaintedAccessor('Node', n, 'textContent');\n}\n\nexport function contains(n: Node, other: Node): boolean {\n return getUntaintedMethod('Node', n, 'contains')(other);\n}\n\nexport function getRootNode(n: Node): Node {\n return getUntaintedMethod('Node', n, 'getRootNode')();\n}\n\nexport function host(n: ShadowRoot): Element | null {\n if (!n || !('host' in n)) return null;\n return getUntaintedAccessor('ShadowRoot', n, 'host');\n}\n\nexport function styleSheets(n: ShadowRoot): StyleSheetList {\n return n.styleSheets;\n}\n\nexport function shadowRoot(n: Node): ShadowRoot | null {\n if (!n || !('shadowRoot' in n)) return null;\n return getUntaintedAccessor('Element', n as Element, 'shadowRoot');\n}\n\nexport function querySelector(n: Element, selectors: string): Element | null {\n return getUntaintedAccessor('Element', n, 'querySelector')(selectors);\n}\n\nexport function querySelectorAll(\n n: Element,\n selectors: string,\n): NodeListOf<Element> {\n return getUntaintedAccessor('Element', n, 'querySelectorAll')(selectors);\n}\n\nexport function mutationObserverCtor(): (typeof MutationObserver)['prototype']['constructor'] {\n return getUntaintedPrototype('MutationObserver').constructor;\n}\n\nexport default {\n childNodes,\n parentNode,\n parentElement,\n textContent,\n contains,\n getRootNode,\n host,\n styleSheets,\n shadowRoot,\n querySelector,\n querySelectorAll,\n mutationObserver: mutationObserverCtor,\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rrweb-utils.js","sources":["../src/index.ts"],"sourcesContent":["type PrototypeOwner = Node | ShadowRoot | MutationObserver | Element;\ntype TypeofPrototypeOwner =\n | typeof Node\n | typeof ShadowRoot\n | typeof MutationObserver\n | typeof Element;\n\ntype BasePrototypeCache = {\n Node: typeof Node.prototype;\n ShadowRoot: typeof ShadowRoot.prototype;\n MutationObserver: typeof MutationObserver.prototype;\n Element: typeof Element.prototype;\n};\n\nconst testableAccessors = {\n Node: ['childNodes', 'parentNode', 'parentElement', 'textContent'] as const,\n ShadowRoot: ['host', 'styleSheets'] as const,\n Element: ['shadowRoot', 'querySelector', 'querySelectorAll'] as const,\n MutationObserver: [] as const,\n} as const;\n\nconst testableMethods = {\n Node: ['contains', 'getRootNode'] as const,\n ShadowRoot: ['getSelection'],\n Element: [],\n MutationObserver: ['constructor'],\n} as const;\n\nconst untaintedBasePrototype: Partial<BasePrototypeCache> = {};\n\n/*\n When angular patches things - particularly the MutationObserver -\n they pass the `isNativeFunction` check\n That then causes performance issues\n because Angular's change detection\n doesn't like sharing a mutation observer\n Checking for the presence of the Zone object\n on global is a good-enough proxy for Angular\n to cover most cases\n (you can configure zone.js to have a different name\n on the global object and should then manually run rrweb\n outside the Zone)\n */\nexport const isAngularZonePresent = (): boolean => {\n return !!(globalThis as { Zone?: unknown }).Zone;\n};\n\nexport function getUntaintedPrototype<T extends keyof BasePrototypeCache>(\n key: T,\n): BasePrototypeCache[T] {\n if (untaintedBasePrototype[key])\n return untaintedBasePrototype[key] as BasePrototypeCache[T];\n\n const defaultObj = globalThis[key] as TypeofPrototypeOwner;\n const defaultPrototype = defaultObj.prototype as BasePrototypeCache[T];\n\n // use list of testable accessors to check if the prototype is tainted\n const accessorNames =\n key in testableAccessors ? testableAccessors[key] : undefined;\n const isUntaintedAccessors = Boolean(\n accessorNames &&\n // @ts-expect-error 2345\n accessorNames.every((accessor: keyof typeof defaultPrototype) =>\n Boolean(\n Object.getOwnPropertyDescriptor(defaultPrototype, accessor)\n ?.get?.toString()\n .includes('[native code]'),\n ),\n ),\n );\n\n const methodNames = key in testableMethods ? testableMethods[key] : undefined;\n const isUntaintedMethods = Boolean(\n methodNames &&\n methodNames.every(\n // @ts-expect-error 2345\n (method: keyof typeof defaultPrototype) =>\n typeof defaultPrototype[method] === 'function' &&\n defaultPrototype[method]?.toString().includes('[native code]'),\n ),\n );\n\n if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {\n untaintedBasePrototype[key] = defaultObj.prototype as BasePrototypeCache[T];\n return defaultObj.prototype as BasePrototypeCache[T];\n }\n\n try {\n const iframeEl = document.createElement('iframe');\n document.body.appendChild(iframeEl);\n const win = iframeEl.contentWindow;\n if (!win) return defaultObj.prototype as BasePrototypeCache[T];\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n const untaintedObject = (win as any)[key]\n .prototype as BasePrototypeCache[T];\n // cleanup\n document.body.removeChild(iframeEl);\n\n if (!untaintedObject) return defaultPrototype;\n\n return (untaintedBasePrototype[key] = untaintedObject);\n } catch {\n return defaultPrototype;\n }\n}\n\nconst untaintedAccessorCache: Record<\n string,\n (this: PrototypeOwner, ...args: unknown[]) => unknown\n> = {};\n\nexport function getUntaintedAccessor<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n accessor: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(accessor)}`;\n if (untaintedAccessorCache[cacheKey])\n return untaintedAccessorCache[cacheKey].call(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const untaintedAccessor = Object.getOwnPropertyDescriptor(\n untaintedPrototype,\n accessor,\n )?.get;\n\n if (!untaintedAccessor) return instance[accessor];\n\n untaintedAccessorCache[cacheKey] = untaintedAccessor;\n\n return untaintedAccessor.call(instance) as BasePrototypeCache[K][T];\n}\n\ntype BaseMethod<K extends keyof BasePrototypeCache> = (\n this: BasePrototypeCache[K],\n ...args: unknown[]\n) => unknown;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst untaintedMethodCache: Record<string, BaseMethod<any>> = {};\nexport function getUntaintedMethod<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n method: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(method)}`;\n if (untaintedMethodCache[cacheKey])\n return untaintedMethodCache[cacheKey].bind(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n const untaintedMethod = untaintedPrototype[method];\n\n if (typeof untaintedMethod !== 'function') return instance[method];\n\n untaintedMethodCache[cacheKey] = untaintedMethod as BaseMethod<K>;\n\n return untaintedMethod.bind(instance) as BasePrototypeCache[K][T];\n}\n\nexport function childNodes(n: Node): NodeListOf<Node> {\n return getUntaintedAccessor('Node', n, 'childNodes');\n}\n\nexport function parentNode(n: Node): ParentNode | null {\n return getUntaintedAccessor('Node', n, 'parentNode');\n}\n\nexport function parentElement(n: Node): HTMLElement | null {\n return getUntaintedAccessor('Node', n, 'parentElement');\n}\n\nexport function textContent(n: Node): string | null {\n return getUntaintedAccessor('Node', n, 'textContent');\n}\n\nexport function contains(n: Node, other: Node): boolean {\n return getUntaintedMethod('Node', n, 'contains')(other);\n}\n\nexport function getRootNode(n: Node): Node {\n return getUntaintedMethod('Node', n, 'getRootNode')();\n}\n\nexport function host(n: ShadowRoot): Element | null {\n if (!n || !('host' in n)) return null;\n return getUntaintedAccessor('ShadowRoot', n, 'host');\n}\n\nexport function styleSheets(n: ShadowRoot): StyleSheetList {\n return n.styleSheets;\n}\n\nexport function shadowRoot(n: Node): ShadowRoot | null {\n if (!n || !('shadowRoot' in n)) return null;\n return getUntaintedAccessor('Element', n as Element, 'shadowRoot');\n}\n\nexport function querySelector(n: Element, selectors: string): Element | null {\n return getUntaintedAccessor('Element', n, 'querySelector')(selectors);\n}\n\nexport function querySelectorAll(\n n: Element,\n selectors: string,\n): NodeListOf<Element> {\n return getUntaintedAccessor('Element', n, 'querySelectorAll')(selectors);\n}\n\nexport function mutationObserverCtor(): (typeof MutationObserver)['prototype']['constructor'] {\n return getUntaintedPrototype('MutationObserver').constructor;\n}\n\n// copy from https://github.com/getsentry/sentry-javascript/blob/b2109071975af8bf0316d3b5b38f519bdaf5dc15/packages/utils/src/object.ts\nexport function patch(\n source: { [key: string]: any },\n name: string,\n replacement: (...args: unknown[]) => unknown,\n): () => void {\n try {\n if (!(name in source)) {\n return () => {\n //\n };\n }\n\n const original = source[name] as () => unknown;\n const wrapped = replacement(original);\n\n // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work\n // otherwise it'll throw \"TypeError: Object.defineProperties called on non-object\"\n if (typeof wrapped === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n wrapped.prototype = wrapped.prototype || {};\n Object.defineProperties(wrapped, {\n __rrweb_original__: {\n enumerable: false,\n value: original,\n },\n });\n }\n\n source[name] = wrapped;\n\n return () => {\n source[name] = original;\n };\n } catch {\n return () => {\n //\n };\n // This can throw if multiple fill happens on a global object like XMLHttpRequest\n // Fixes https://github.com/getsentry/sentry-javascript/issues/2043\n }\n}\n\nexport default {\n childNodes,\n parentNode,\n parentElement,\n textContent,\n contains,\n getRootNode,\n host,\n styleSheets,\n shadowRoot,\n querySelector,\n querySelectorAll,\n mutationObserver: mutationObserverCtor,\n patch,\n};\n"],"names":[],"mappings":"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"}
@@ -141,6 +141,32 @@ function querySelectorAll(n, selectors) {
141
141
  function mutationObserverCtor() {
142
142
  return getUntaintedPrototype("MutationObserver").constructor;
143
143
  }
144
+ function patch(source, name, replacement) {
145
+ try {
146
+ if (!(name in source)) {
147
+ return () => {
148
+ };
149
+ }
150
+ const original = source[name];
151
+ const wrapped = replacement(original);
152
+ if (typeof wrapped === "function") {
153
+ wrapped.prototype = wrapped.prototype || {};
154
+ Object.defineProperties(wrapped, {
155
+ __rrweb_original__: {
156
+ enumerable: false,
157
+ value: original
158
+ }
159
+ });
160
+ }
161
+ source[name] = wrapped;
162
+ return () => {
163
+ source[name] = original;
164
+ };
165
+ } catch (e) {
166
+ return () => {
167
+ };
168
+ }
169
+ }
144
170
  const index = {
145
171
  childNodes,
146
172
  parentNode,
@@ -153,7 +179,8 @@ const index = {
153
179
  shadowRoot,
154
180
  querySelector,
155
181
  querySelectorAll,
156
- mutationObserver: mutationObserverCtor
182
+ mutationObserver: mutationObserverCtor,
183
+ patch
157
184
  };
158
185
  exports.childNodes = childNodes;
159
186
  exports.contains = contains;
@@ -167,6 +194,7 @@ exports.isAngularZonePresent = isAngularZonePresent;
167
194
  exports.mutationObserverCtor = mutationObserverCtor;
168
195
  exports.parentElement = parentElement;
169
196
  exports.parentNode = parentNode;
197
+ exports.patch = patch;
170
198
  exports.querySelector = querySelector;
171
199
  exports.querySelectorAll = querySelectorAll;
172
200
  exports.shadowRoot = shadowRoot;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["type PrototypeOwner = Node | ShadowRoot | MutationObserver | Element;\ntype TypeofPrototypeOwner =\n | typeof Node\n | typeof ShadowRoot\n | typeof MutationObserver\n | typeof Element;\n\ntype BasePrototypeCache = {\n Node: typeof Node.prototype;\n ShadowRoot: typeof ShadowRoot.prototype;\n MutationObserver: typeof MutationObserver.prototype;\n Element: typeof Element.prototype;\n};\n\nconst testableAccessors = {\n Node: ['childNodes', 'parentNode', 'parentElement', 'textContent'] as const,\n ShadowRoot: ['host', 'styleSheets'] as const,\n Element: ['shadowRoot', 'querySelector', 'querySelectorAll'] as const,\n MutationObserver: [] as const,\n} as const;\n\nconst testableMethods = {\n Node: ['contains', 'getRootNode'] as const,\n ShadowRoot: ['getSelection'],\n Element: [],\n MutationObserver: ['constructor'],\n} as const;\n\nconst untaintedBasePrototype: Partial<BasePrototypeCache> = {};\n\n/*\n When angular patches things - particularly the MutationObserver -\n they pass the `isNativeFunction` check\n That then causes performance issues\n because Angular's change detection\n doesn't like sharing a mutation observer\n Checking for the presence of the Zone object\n on global is a good-enough proxy for Angular\n to cover most cases\n (you can configure zone.js to have a different name\n on the global object and should then manually run rrweb\n outside the Zone)\n */\nexport const isAngularZonePresent = (): boolean => {\n return !!(globalThis as { Zone?: unknown }).Zone;\n};\n\nexport function getUntaintedPrototype<T extends keyof BasePrototypeCache>(\n key: T,\n): BasePrototypeCache[T] {\n if (untaintedBasePrototype[key])\n return untaintedBasePrototype[key] as BasePrototypeCache[T];\n\n const defaultObj = globalThis[key] as TypeofPrototypeOwner;\n const defaultPrototype = defaultObj.prototype as BasePrototypeCache[T];\n\n // use list of testable accessors to check if the prototype is tainted\n const accessorNames =\n key in testableAccessors ? testableAccessors[key] : undefined;\n const isUntaintedAccessors = Boolean(\n accessorNames &&\n // @ts-expect-error 2345\n accessorNames.every((accessor: keyof typeof defaultPrototype) =>\n Boolean(\n Object.getOwnPropertyDescriptor(defaultPrototype, accessor)\n ?.get?.toString()\n .includes('[native code]'),\n ),\n ),\n );\n\n const methodNames = key in testableMethods ? testableMethods[key] : undefined;\n const isUntaintedMethods = Boolean(\n methodNames &&\n methodNames.every(\n // @ts-expect-error 2345\n (method: keyof typeof defaultPrototype) =>\n typeof defaultPrototype[method] === 'function' &&\n defaultPrototype[method]?.toString().includes('[native code]'),\n ),\n );\n\n if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {\n untaintedBasePrototype[key] = defaultObj.prototype as BasePrototypeCache[T];\n return defaultObj.prototype as BasePrototypeCache[T];\n }\n\n try {\n const iframeEl = document.createElement('iframe');\n document.body.appendChild(iframeEl);\n const win = iframeEl.contentWindow;\n if (!win) return defaultObj.prototype as BasePrototypeCache[T];\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n const untaintedObject = (win as any)[key]\n .prototype as BasePrototypeCache[T];\n // cleanup\n document.body.removeChild(iframeEl);\n\n if (!untaintedObject) return defaultPrototype;\n\n return (untaintedBasePrototype[key] = untaintedObject);\n } catch {\n return defaultPrototype;\n }\n}\n\nconst untaintedAccessorCache: Record<\n string,\n (this: PrototypeOwner, ...args: unknown[]) => unknown\n> = {};\n\nexport function getUntaintedAccessor<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n accessor: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(accessor)}`;\n if (untaintedAccessorCache[cacheKey])\n return untaintedAccessorCache[cacheKey].call(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const untaintedAccessor = Object.getOwnPropertyDescriptor(\n untaintedPrototype,\n accessor,\n )?.get;\n\n if (!untaintedAccessor) return instance[accessor];\n\n untaintedAccessorCache[cacheKey] = untaintedAccessor;\n\n return untaintedAccessor.call(instance) as BasePrototypeCache[K][T];\n}\n\ntype BaseMethod<K extends keyof BasePrototypeCache> = (\n this: BasePrototypeCache[K],\n ...args: unknown[]\n) => unknown;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst untaintedMethodCache: Record<string, BaseMethod<any>> = {};\nexport function getUntaintedMethod<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n method: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(method)}`;\n if (untaintedMethodCache[cacheKey])\n return untaintedMethodCache[cacheKey].bind(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n const untaintedMethod = untaintedPrototype[method];\n\n if (typeof untaintedMethod !== 'function') return instance[method];\n\n untaintedMethodCache[cacheKey] = untaintedMethod as BaseMethod<K>;\n\n return untaintedMethod.bind(instance) as BasePrototypeCache[K][T];\n}\n\nexport function childNodes(n: Node): NodeListOf<Node> {\n return getUntaintedAccessor('Node', n, 'childNodes');\n}\n\nexport function parentNode(n: Node): ParentNode | null {\n return getUntaintedAccessor('Node', n, 'parentNode');\n}\n\nexport function parentElement(n: Node): HTMLElement | null {\n return getUntaintedAccessor('Node', n, 'parentElement');\n}\n\nexport function textContent(n: Node): string | null {\n return getUntaintedAccessor('Node', n, 'textContent');\n}\n\nexport function contains(n: Node, other: Node): boolean {\n return getUntaintedMethod('Node', n, 'contains')(other);\n}\n\nexport function getRootNode(n: Node): Node {\n return getUntaintedMethod('Node', n, 'getRootNode')();\n}\n\nexport function host(n: ShadowRoot): Element | null {\n if (!n || !('host' in n)) return null;\n return getUntaintedAccessor('ShadowRoot', n, 'host');\n}\n\nexport function styleSheets(n: ShadowRoot): StyleSheetList {\n return n.styleSheets;\n}\n\nexport function shadowRoot(n: Node): ShadowRoot | null {\n if (!n || !('shadowRoot' in n)) return null;\n return getUntaintedAccessor('Element', n as Element, 'shadowRoot');\n}\n\nexport function querySelector(n: Element, selectors: string): Element | null {\n return getUntaintedAccessor('Element', n, 'querySelector')(selectors);\n}\n\nexport function querySelectorAll(\n n: Element,\n selectors: string,\n): NodeListOf<Element> {\n return getUntaintedAccessor('Element', n, 'querySelectorAll')(selectors);\n}\n\nexport function mutationObserverCtor(): (typeof MutationObserver)['prototype']['constructor'] {\n return getUntaintedPrototype('MutationObserver').constructor;\n}\n\nexport default {\n childNodes,\n parentNode,\n parentElement,\n textContent,\n contains,\n getRootNode,\n host,\n styleSheets,\n shadowRoot,\n querySelector,\n querySelectorAll,\n mutationObserver: mutationObserverCtor,\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["type PrototypeOwner = Node | ShadowRoot | MutationObserver | Element;\ntype TypeofPrototypeOwner =\n | typeof Node\n | typeof ShadowRoot\n | typeof MutationObserver\n | typeof Element;\n\ntype BasePrototypeCache = {\n Node: typeof Node.prototype;\n ShadowRoot: typeof ShadowRoot.prototype;\n MutationObserver: typeof MutationObserver.prototype;\n Element: typeof Element.prototype;\n};\n\nconst testableAccessors = {\n Node: ['childNodes', 'parentNode', 'parentElement', 'textContent'] as const,\n ShadowRoot: ['host', 'styleSheets'] as const,\n Element: ['shadowRoot', 'querySelector', 'querySelectorAll'] as const,\n MutationObserver: [] as const,\n} as const;\n\nconst testableMethods = {\n Node: ['contains', 'getRootNode'] as const,\n ShadowRoot: ['getSelection'],\n Element: [],\n MutationObserver: ['constructor'],\n} as const;\n\nconst untaintedBasePrototype: Partial<BasePrototypeCache> = {};\n\n/*\n When angular patches things - particularly the MutationObserver -\n they pass the `isNativeFunction` check\n That then causes performance issues\n because Angular's change detection\n doesn't like sharing a mutation observer\n Checking for the presence of the Zone object\n on global is a good-enough proxy for Angular\n to cover most cases\n (you can configure zone.js to have a different name\n on the global object and should then manually run rrweb\n outside the Zone)\n */\nexport const isAngularZonePresent = (): boolean => {\n return !!(globalThis as { Zone?: unknown }).Zone;\n};\n\nexport function getUntaintedPrototype<T extends keyof BasePrototypeCache>(\n key: T,\n): BasePrototypeCache[T] {\n if (untaintedBasePrototype[key])\n return untaintedBasePrototype[key] as BasePrototypeCache[T];\n\n const defaultObj = globalThis[key] as TypeofPrototypeOwner;\n const defaultPrototype = defaultObj.prototype as BasePrototypeCache[T];\n\n // use list of testable accessors to check if the prototype is tainted\n const accessorNames =\n key in testableAccessors ? testableAccessors[key] : undefined;\n const isUntaintedAccessors = Boolean(\n accessorNames &&\n // @ts-expect-error 2345\n accessorNames.every((accessor: keyof typeof defaultPrototype) =>\n Boolean(\n Object.getOwnPropertyDescriptor(defaultPrototype, accessor)\n ?.get?.toString()\n .includes('[native code]'),\n ),\n ),\n );\n\n const methodNames = key in testableMethods ? testableMethods[key] : undefined;\n const isUntaintedMethods = Boolean(\n methodNames &&\n methodNames.every(\n // @ts-expect-error 2345\n (method: keyof typeof defaultPrototype) =>\n typeof defaultPrototype[method] === 'function' &&\n defaultPrototype[method]?.toString().includes('[native code]'),\n ),\n );\n\n if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {\n untaintedBasePrototype[key] = defaultObj.prototype as BasePrototypeCache[T];\n return defaultObj.prototype as BasePrototypeCache[T];\n }\n\n try {\n const iframeEl = document.createElement('iframe');\n document.body.appendChild(iframeEl);\n const win = iframeEl.contentWindow;\n if (!win) return defaultObj.prototype as BasePrototypeCache[T];\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n const untaintedObject = (win as any)[key]\n .prototype as BasePrototypeCache[T];\n // cleanup\n document.body.removeChild(iframeEl);\n\n if (!untaintedObject) return defaultPrototype;\n\n return (untaintedBasePrototype[key] = untaintedObject);\n } catch {\n return defaultPrototype;\n }\n}\n\nconst untaintedAccessorCache: Record<\n string,\n (this: PrototypeOwner, ...args: unknown[]) => unknown\n> = {};\n\nexport function getUntaintedAccessor<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n accessor: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(accessor)}`;\n if (untaintedAccessorCache[cacheKey])\n return untaintedAccessorCache[cacheKey].call(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const untaintedAccessor = Object.getOwnPropertyDescriptor(\n untaintedPrototype,\n accessor,\n )?.get;\n\n if (!untaintedAccessor) return instance[accessor];\n\n untaintedAccessorCache[cacheKey] = untaintedAccessor;\n\n return untaintedAccessor.call(instance) as BasePrototypeCache[K][T];\n}\n\ntype BaseMethod<K extends keyof BasePrototypeCache> = (\n this: BasePrototypeCache[K],\n ...args: unknown[]\n) => unknown;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst untaintedMethodCache: Record<string, BaseMethod<any>> = {};\nexport function getUntaintedMethod<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n method: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(method)}`;\n if (untaintedMethodCache[cacheKey])\n return untaintedMethodCache[cacheKey].bind(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n const untaintedMethod = untaintedPrototype[method];\n\n if (typeof untaintedMethod !== 'function') return instance[method];\n\n untaintedMethodCache[cacheKey] = untaintedMethod as BaseMethod<K>;\n\n return untaintedMethod.bind(instance) as BasePrototypeCache[K][T];\n}\n\nexport function childNodes(n: Node): NodeListOf<Node> {\n return getUntaintedAccessor('Node', n, 'childNodes');\n}\n\nexport function parentNode(n: Node): ParentNode | null {\n return getUntaintedAccessor('Node', n, 'parentNode');\n}\n\nexport function parentElement(n: Node): HTMLElement | null {\n return getUntaintedAccessor('Node', n, 'parentElement');\n}\n\nexport function textContent(n: Node): string | null {\n return getUntaintedAccessor('Node', n, 'textContent');\n}\n\nexport function contains(n: Node, other: Node): boolean {\n return getUntaintedMethod('Node', n, 'contains')(other);\n}\n\nexport function getRootNode(n: Node): Node {\n return getUntaintedMethod('Node', n, 'getRootNode')();\n}\n\nexport function host(n: ShadowRoot): Element | null {\n if (!n || !('host' in n)) return null;\n return getUntaintedAccessor('ShadowRoot', n, 'host');\n}\n\nexport function styleSheets(n: ShadowRoot): StyleSheetList {\n return n.styleSheets;\n}\n\nexport function shadowRoot(n: Node): ShadowRoot | null {\n if (!n || !('shadowRoot' in n)) return null;\n return getUntaintedAccessor('Element', n as Element, 'shadowRoot');\n}\n\nexport function querySelector(n: Element, selectors: string): Element | null {\n return getUntaintedAccessor('Element', n, 'querySelector')(selectors);\n}\n\nexport function querySelectorAll(\n n: Element,\n selectors: string,\n): NodeListOf<Element> {\n return getUntaintedAccessor('Element', n, 'querySelectorAll')(selectors);\n}\n\nexport function mutationObserverCtor(): (typeof MutationObserver)['prototype']['constructor'] {\n return getUntaintedPrototype('MutationObserver').constructor;\n}\n\n// copy from https://github.com/getsentry/sentry-javascript/blob/b2109071975af8bf0316d3b5b38f519bdaf5dc15/packages/utils/src/object.ts\nexport function patch(\n source: { [key: string]: any },\n name: string,\n replacement: (...args: unknown[]) => unknown,\n): () => void {\n try {\n if (!(name in source)) {\n return () => {\n //\n };\n }\n\n const original = source[name] as () => unknown;\n const wrapped = replacement(original);\n\n // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work\n // otherwise it'll throw \"TypeError: Object.defineProperties called on non-object\"\n if (typeof wrapped === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n wrapped.prototype = wrapped.prototype || {};\n Object.defineProperties(wrapped, {\n __rrweb_original__: {\n enumerable: false,\n value: original,\n },\n });\n }\n\n source[name] = wrapped;\n\n return () => {\n source[name] = original;\n };\n } catch {\n return () => {\n //\n };\n // This can throw if multiple fill happens on a global object like XMLHttpRequest\n // Fixes https://github.com/getsentry/sentry-javascript/issues/2043\n }\n}\n\nexport default {\n childNodes,\n parentNode,\n parentElement,\n textContent,\n contains,\n getRootNode,\n host,\n styleSheets,\n shadowRoot,\n querySelector,\n querySelectorAll,\n mutationObserver: mutationObserverCtor,\n patch,\n};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -11,7 +11,7 @@
11
11
  }(this, () => {
12
12
  var exports = {};
13
13
  var module = { exports };
14
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const y={Node:["childNodes","parentNode","parentElement","textContent"],ShadowRoot:["host","styleSheets"],Element:["shadowRoot","querySelector","querySelectorAll"],MutationObserver:[]},v={Node:["contains","getRootNode"],ShadowRoot:["getSelection"],Element:[],MutationObserver:["constructor"]},l={},N=()=>!!globalThis.Zone;function f(t){if(l[t])return l[t];const e=globalThis[t],o=e.prototype,n=t in y?y[t]:void 0,s=!!(n&&n.every(r=>{var c,a;return!!((a=(c=Object.getOwnPropertyDescriptor(o,r))==null?void 0:c.get)!=null&&a.toString().includes("[native code]"))})),u=t in v?v[t]:void 0,d=!!(u&&u.every(r=>{var c;return typeof o[r]=="function"&&((c=o[r])==null?void 0:c.toString().includes("[native code]"))}));if(s&&d&&!N())return l[t]=e.prototype,e.prototype;try{const r=document.createElement("iframe");document.body.appendChild(r);const c=r.contentWindow;if(!c)return e.prototype;const a=c[t].prototype;return document.body.removeChild(r),a?l[t]=a:o}catch(r){return o}}const h={};function i(t,e,o){var n;const s=`${t}.${String(o)}`;if(h[s])return h[s].call(e);const u=f(t),d=(n=Object.getOwnPropertyDescriptor(u,o))==null?void 0:n.get;return d?(h[s]=d,d.call(e)):e[o]}const p={};function g(t,e,o){const n=`${t}.${String(o)}`;if(p[n])return p[n].bind(e);const u=f(t)[o];return typeof u!="function"?e[o]:(p[n]=u,u.bind(e))}function S(t){return i("Node",t,"childNodes")}function b(t){return i("Node",t,"parentNode")}function m(t){return i("Node",t,"parentElement")}function O(t){return i("Node",t,"textContent")}function w(t,e){return g("Node",t,"contains")(e)}function A(t){return g("Node",t,"getRootNode")()}function P(t){return!t||!("host"in t)?null:i("ShadowRoot",t,"host")}function R(t){return t.styleSheets}function E(t){return!t||!("shadowRoot"in t)?null:i("Element",t,"shadowRoot")}function M(t,e){return i("Element",t,"querySelector")(e)}function C(t,e){return i("Element",t,"querySelectorAll")(e)}function q(){return f("MutationObserver").constructor}const U={childNodes:S,parentNode:b,parentElement:m,textContent:O,contains:w,getRootNode:A,host:P,styleSheets:R,shadowRoot:E,querySelector:M,querySelectorAll:C,mutationObserver:q};exports.childNodes=S;exports.contains=w;exports.default=U;exports.getRootNode=A;exports.getUntaintedAccessor=i;exports.getUntaintedMethod=g;exports.getUntaintedPrototype=f;exports.host=P;exports.isAngularZonePresent=N;exports.mutationObserverCtor=q;exports.parentElement=m;exports.parentNode=b;exports.querySelector=M;exports.querySelectorAll=C;exports.shadowRoot=E;exports.styleSheets=R;exports.textContent=O;
14
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const g={Node:["childNodes","parentNode","parentElement","textContent"],ShadowRoot:["host","styleSheets"],Element:["shadowRoot","querySelector","querySelectorAll"],MutationObserver:[]},b={Node:["contains","getRootNode"],ShadowRoot:["getSelection"],Element:[],MutationObserver:["constructor"]},l={},v=()=>!!globalThis.Zone;function p(t){if(l[t])return l[t];const e=globalThis[t],o=e.prototype,n=t in g?g[t]:void 0,r=!!(n&&n.every(i=>{var s,a;return!!((a=(s=Object.getOwnPropertyDescriptor(o,i))==null?void 0:s.get)!=null&&a.toString().includes("[native code]"))})),u=t in b?b[t]:void 0,d=!!(u&&u.every(i=>{var s;return typeof o[i]=="function"&&((s=o[i])==null?void 0:s.toString().includes("[native code]"))}));if(r&&d&&!v())return l[t]=e.prototype,e.prototype;try{const i=document.createElement("iframe");document.body.appendChild(i);const s=i.contentWindow;if(!s)return e.prototype;const a=s[t].prototype;return document.body.removeChild(i),a?l[t]=a:o}catch(i){return o}}const f={};function c(t,e,o){var n;const r=`${t}.${String(o)}`;if(f[r])return f[r].call(e);const u=p(t),d=(n=Object.getOwnPropertyDescriptor(u,o))==null?void 0:n.get;return d?(f[r]=d,d.call(e)):e[o]}const h={};function y(t,e,o){const n=`${t}.${String(o)}`;if(h[n])return h[n].bind(e);const u=p(t)[o];return typeof u!="function"?e[o]:(h[n]=u,u.bind(e))}function N(t){return c("Node",t,"childNodes")}function S(t){return c("Node",t,"parentNode")}function m(t){return c("Node",t,"parentElement")}function w(t){return c("Node",t,"textContent")}function O(t,e){return y("Node",t,"contains")(e)}function P(t){return y("Node",t,"getRootNode")()}function A(t){return!t||!("host"in t)?null:c("ShadowRoot",t,"host")}function R(t){return t.styleSheets}function E(t){return!t||!("shadowRoot"in t)?null:c("Element",t,"shadowRoot")}function M(t,e){return c("Element",t,"querySelector")(e)}function _(t,e){return c("Element",t,"querySelectorAll")(e)}function C(){return p("MutationObserver").constructor}function q(t,e,o){try{if(!(e in t))return()=>{};const n=t[e],r=o(n);return typeof r=="function"&&(r.prototype=r.prototype||{},Object.defineProperties(r,{__rrweb_original__:{enumerable:!1,value:n}})),t[e]=r,()=>{t[e]=n}}catch(n){return()=>{}}}const U={childNodes:N,parentNode:S,parentElement:m,textContent:w,contains:O,getRootNode:P,host:A,styleSheets:R,shadowRoot:E,querySelector:M,querySelectorAll:_,mutationObserver:C,patch:q};exports.childNodes=N;exports.contains=O;exports.default=U;exports.getRootNode=P;exports.getUntaintedAccessor=c;exports.getUntaintedMethod=y;exports.getUntaintedPrototype=p;exports.host=A;exports.isAngularZonePresent=v;exports.mutationObserverCtor=C;exports.parentElement=m;exports.parentNode=S;exports.patch=q;exports.querySelector=M;exports.querySelectorAll=_;exports.shadowRoot=E;exports.styleSheets=R;exports.textContent=w;
15
15
  if (typeof module.exports == "object" && typeof exports == "object") {
16
16
  var __cp = (to, from, except, desc) => {
17
17
  if ((from && typeof from === "object") || typeof from === "function") {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["type PrototypeOwner = Node | ShadowRoot | MutationObserver | Element;\ntype TypeofPrototypeOwner =\n | typeof Node\n | typeof ShadowRoot\n | typeof MutationObserver\n | typeof Element;\n\ntype BasePrototypeCache = {\n Node: typeof Node.prototype;\n ShadowRoot: typeof ShadowRoot.prototype;\n MutationObserver: typeof MutationObserver.prototype;\n Element: typeof Element.prototype;\n};\n\nconst testableAccessors = {\n Node: ['childNodes', 'parentNode', 'parentElement', 'textContent'] as const,\n ShadowRoot: ['host', 'styleSheets'] as const,\n Element: ['shadowRoot', 'querySelector', 'querySelectorAll'] as const,\n MutationObserver: [] as const,\n} as const;\n\nconst testableMethods = {\n Node: ['contains', 'getRootNode'] as const,\n ShadowRoot: ['getSelection'],\n Element: [],\n MutationObserver: ['constructor'],\n} as const;\n\nconst untaintedBasePrototype: Partial<BasePrototypeCache> = {};\n\n/*\n When angular patches things - particularly the MutationObserver -\n they pass the `isNativeFunction` check\n That then causes performance issues\n because Angular's change detection\n doesn't like sharing a mutation observer\n Checking for the presence of the Zone object\n on global is a good-enough proxy for Angular\n to cover most cases\n (you can configure zone.js to have a different name\n on the global object and should then manually run rrweb\n outside the Zone)\n */\nexport const isAngularZonePresent = (): boolean => {\n return !!(globalThis as { Zone?: unknown }).Zone;\n};\n\nexport function getUntaintedPrototype<T extends keyof BasePrototypeCache>(\n key: T,\n): BasePrototypeCache[T] {\n if (untaintedBasePrototype[key])\n return untaintedBasePrototype[key] as BasePrototypeCache[T];\n\n const defaultObj = globalThis[key] as TypeofPrototypeOwner;\n const defaultPrototype = defaultObj.prototype as BasePrototypeCache[T];\n\n // use list of testable accessors to check if the prototype is tainted\n const accessorNames =\n key in testableAccessors ? testableAccessors[key] : undefined;\n const isUntaintedAccessors = Boolean(\n accessorNames &&\n // @ts-expect-error 2345\n accessorNames.every((accessor: keyof typeof defaultPrototype) =>\n Boolean(\n Object.getOwnPropertyDescriptor(defaultPrototype, accessor)\n ?.get?.toString()\n .includes('[native code]'),\n ),\n ),\n );\n\n const methodNames = key in testableMethods ? testableMethods[key] : undefined;\n const isUntaintedMethods = Boolean(\n methodNames &&\n methodNames.every(\n // @ts-expect-error 2345\n (method: keyof typeof defaultPrototype) =>\n typeof defaultPrototype[method] === 'function' &&\n defaultPrototype[method]?.toString().includes('[native code]'),\n ),\n );\n\n if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {\n untaintedBasePrototype[key] = defaultObj.prototype as BasePrototypeCache[T];\n return defaultObj.prototype as BasePrototypeCache[T];\n }\n\n try {\n const iframeEl = document.createElement('iframe');\n document.body.appendChild(iframeEl);\n const win = iframeEl.contentWindow;\n if (!win) return defaultObj.prototype as BasePrototypeCache[T];\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n const untaintedObject = (win as any)[key]\n .prototype as BasePrototypeCache[T];\n // cleanup\n document.body.removeChild(iframeEl);\n\n if (!untaintedObject) return defaultPrototype;\n\n return (untaintedBasePrototype[key] = untaintedObject);\n } catch {\n return defaultPrototype;\n }\n}\n\nconst untaintedAccessorCache: Record<\n string,\n (this: PrototypeOwner, ...args: unknown[]) => unknown\n> = {};\n\nexport function getUntaintedAccessor<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n accessor: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(accessor)}`;\n if (untaintedAccessorCache[cacheKey])\n return untaintedAccessorCache[cacheKey].call(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const untaintedAccessor = Object.getOwnPropertyDescriptor(\n untaintedPrototype,\n accessor,\n )?.get;\n\n if (!untaintedAccessor) return instance[accessor];\n\n untaintedAccessorCache[cacheKey] = untaintedAccessor;\n\n return untaintedAccessor.call(instance) as BasePrototypeCache[K][T];\n}\n\ntype BaseMethod<K extends keyof BasePrototypeCache> = (\n this: BasePrototypeCache[K],\n ...args: unknown[]\n) => unknown;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst untaintedMethodCache: Record<string, BaseMethod<any>> = {};\nexport function getUntaintedMethod<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n method: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(method)}`;\n if (untaintedMethodCache[cacheKey])\n return untaintedMethodCache[cacheKey].bind(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n const untaintedMethod = untaintedPrototype[method];\n\n if (typeof untaintedMethod !== 'function') return instance[method];\n\n untaintedMethodCache[cacheKey] = untaintedMethod as BaseMethod<K>;\n\n return untaintedMethod.bind(instance) as BasePrototypeCache[K][T];\n}\n\nexport function childNodes(n: Node): NodeListOf<Node> {\n return getUntaintedAccessor('Node', n, 'childNodes');\n}\n\nexport function parentNode(n: Node): ParentNode | null {\n return getUntaintedAccessor('Node', n, 'parentNode');\n}\n\nexport function parentElement(n: Node): HTMLElement | null {\n return getUntaintedAccessor('Node', n, 'parentElement');\n}\n\nexport function textContent(n: Node): string | null {\n return getUntaintedAccessor('Node', n, 'textContent');\n}\n\nexport function contains(n: Node, other: Node): boolean {\n return getUntaintedMethod('Node', n, 'contains')(other);\n}\n\nexport function getRootNode(n: Node): Node {\n return getUntaintedMethod('Node', n, 'getRootNode')();\n}\n\nexport function host(n: ShadowRoot): Element | null {\n if (!n || !('host' in n)) return null;\n return getUntaintedAccessor('ShadowRoot', n, 'host');\n}\n\nexport function styleSheets(n: ShadowRoot): StyleSheetList {\n return n.styleSheets;\n}\n\nexport function shadowRoot(n: Node): ShadowRoot | null {\n if (!n || !('shadowRoot' in n)) return null;\n return getUntaintedAccessor('Element', n as Element, 'shadowRoot');\n}\n\nexport function querySelector(n: Element, selectors: string): Element | null {\n return getUntaintedAccessor('Element', n, 'querySelector')(selectors);\n}\n\nexport function querySelectorAll(\n n: Element,\n selectors: string,\n): NodeListOf<Element> {\n return getUntaintedAccessor('Element', n, 'querySelectorAll')(selectors);\n}\n\nexport function mutationObserverCtor(): (typeof MutationObserver)['prototype']['constructor'] {\n return getUntaintedPrototype('MutationObserver').constructor;\n}\n\nexport default {\n childNodes,\n parentNode,\n parentElement,\n textContent,\n contains,\n getRootNode,\n host,\n styleSheets,\n shadowRoot,\n querySelector,\n querySelectorAll,\n mutationObserver: mutationObserverCtor,\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;4GAcA,MAAMA,EAAoB,CACxB,KAAM,CAAC,aAAc,aAAc,gBAAiB,aAAa,EACjE,WAAY,CAAC,OAAQ,aAAa,EAClC,QAAS,CAAC,aAAc,gBAAiB,kBAAkB,EAC3D,iBAAkB,CAAC,CACrB,EAEMC,EAAkB,CACtB,KAAM,CAAC,WAAY,aAAa,EAChC,WAAY,CAAC,cAAc,EAC3B,QAAS,CAAC,EACV,iBAAkB,CAAC,aAAa,CAClC,EAEMC,EAAsD,CAAA,EAe/CC,EAAuB,IAC3B,CAAC,CAAE,WAAkC,KAGvC,SAASC,EACdC,EACuB,CACvB,GAAIH,EAAuBG,CAAG,EAC5B,OAAOH,EAAuBG,CAAG,EAE7B,MAAAC,EAAa,WAAWD,CAAG,EAC3BE,EAAmBD,EAAW,UAG9BE,EACJH,KAAOL,EAAoBA,EAAkBK,CAAG,EAAI,OAChDI,EAAuB,GAC3BD,GAEEA,EAAc,MAAOE,GACnB,SAAA,MAAA,IACEC,GAAAC,EAAA,OAAO,yBAAyBL,EAAkBG,CAAQ,IAA1D,KAAA,OAAAE,EACI,MADJ,MAAAD,EACS,SAAA,EACN,SAAS,eAAA,EACd,CACF,GAGEE,EAAcR,KAAOJ,EAAkBA,EAAgBI,CAAG,EAAI,OAC9DS,EAAqB,GACzBD,GACEA,EAAY,MAETE,GACC,OAAA,OAAA,OAAOR,EAAiBQ,CAAM,GAAM,cACpCH,EAAAL,EAAiBQ,CAAM,IAAvB,KAAA,OAAAH,EAA0B,SAAA,EAAW,SAAS,eAAA,EAAA,CAClD,GAGJ,GAAIH,GAAwBK,GAAsB,CAACX,EAAA,EAC1B,OAAAD,EAAAG,CAAG,EAAIC,EAAW,UAClCA,EAAW,UAGhB,GAAA,CACI,MAAAU,EAAW,SAAS,cAAc,QAAQ,EACvC,SAAA,KAAK,YAAYA,CAAQ,EAClC,MAAMC,EAAMD,EAAS,cACjB,GAAA,CAACC,EAAK,OAAOX,EAAW,UAGtB,MAAAY,EAAmBD,EAAYZ,CAAG,EACrC,UAIC,OAFK,SAAA,KAAK,YAAYW,CAAQ,EAE7BE,EAEGhB,EAAuBG,CAAG,EAAIa,EAFTX,CAES,OAChCY,EAAA,CACC,OAAAZ,CACT,CACF,CAEA,MAAMa,EAGF,CAAA,EAEY,SAAAC,EAIdhB,EACAiB,EACAZ,EAC0B,OAC1B,MAAMa,EAAW,GAAGlB,CAAG,IAAI,OAAOK,CAAQ,CAAC,GAC3C,GAAIU,EAAuBG,CAAQ,EAC1B,OAAAH,EAAuBG,CAAQ,EAAE,KACtCD,CAAA,EAGE,MAAAE,EAAqBpB,EAAsBC,CAAG,EAE9CoB,GAAoBb,EAAA,OAAO,yBAC/BY,EACAd,CACC,IAHuB,KAAA,OAAAE,EAGvB,IAEH,OAAKa,GAELL,EAAuBG,CAAQ,EAAIE,EAE5BA,EAAkB,KAAKH,CAAQ,GAJPA,EAASZ,CAAQ,CAKlD,CAQA,MAAMgB,EAAwD,CAAA,EAC9C,SAAAC,EAIdtB,EACAiB,EACAP,EAC0B,CAC1B,MAAMQ,EAAW,GAAGlB,CAAG,IAAI,OAAOU,CAAM,CAAC,GACzC,GAAIW,EAAqBH,CAAQ,EACxB,OAAAG,EAAqBH,CAAQ,EAAE,KACpCD,CAAA,EAIE,MAAAM,EADqBxB,EAAsBC,CAAG,EACTU,CAAM,EAEjD,OAAI,OAAOa,GAAoB,WAAmBN,EAASP,CAAM,GAEjEW,EAAqBH,CAAQ,EAAIK,EAE1BA,EAAgB,KAAKN,CAAQ,EACtC,CAEO,SAASO,EAAWC,EAA2B,CAC7C,OAAAT,EAAqB,OAAQS,EAAG,YAAY,CACrD,CAEO,SAASC,EAAWD,EAA4B,CAC9C,OAAAT,EAAqB,OAAQS,EAAG,YAAY,CACrD,CAEO,SAASE,EAAcF,EAA6B,CAClD,OAAAT,EAAqB,OAAQS,EAAG,eAAe,CACxD,CAEO,SAASG,EAAYH,EAAwB,CAC3C,OAAAT,EAAqB,OAAQS,EAAG,aAAa,CACtD,CAEgB,SAAAI,EAASJ,EAASK,EAAsB,CACtD,OAAOR,EAAmB,OAAQG,EAAG,UAAU,EAAEK,CAAK,CACxD,CAEO,SAASC,EAAYN,EAAe,CACzC,OAAOH,EAAmB,OAAQG,EAAG,aAAa,EAAE,CACtD,CAEO,SAASO,EAAKP,EAA+B,CAClD,MAAI,CAACA,GAAK,EAAE,SAAUA,GAAW,KAC1BT,EAAqB,aAAcS,EAAG,MAAM,CACrD,CAEO,SAASQ,EAAYR,EAA+B,CACzD,OAAOA,EAAE,WACX,CAEO,SAASS,EAAWT,EAA4B,CACrD,MAAI,CAACA,GAAK,EAAE,eAAgBA,GAAW,KAChCT,EAAqB,UAAWS,EAAc,YAAY,CACnE,CAEgB,SAAAU,EAAcV,EAAYW,EAAmC,CAC3E,OAAOpB,EAAqB,UAAWS,EAAG,eAAe,EAAEW,CAAS,CACtE,CAEgB,SAAAC,EACdZ,EACAW,EACqB,CACrB,OAAOpB,EAAqB,UAAWS,EAAG,kBAAkB,EAAEW,CAAS,CACzE,CAEO,SAASE,GAA8E,CACrF,OAAAvC,EAAsB,kBAAkB,EAAE,WACnD,CAEA,MAAewC,EAAA,CACb,WAAAf,EACA,WAAAE,EACA,cAAAC,EACA,YAAAC,EACA,SAAAC,EACA,YAAAE,EACA,KAAAC,EACA,YAAAC,EACA,WAAAC,EACA,cAAAC,EACA,iBAAAE,EACA,iBAAkBC,CACpB",
6
- "names": ["testableAccessors", "testableMethods", "untaintedBasePrototype", "isAngularZonePresent", "getUntaintedPrototype", "key", "defaultObj", "defaultPrototype", "accessorNames", "isUntaintedAccessors", "accessor", "_b", "_a", "methodNames", "isUntaintedMethods", "method", "iframeEl", "win", "untaintedObject", "e", "untaintedAccessorCache", "getUntaintedAccessor", "instance", "cacheKey", "untaintedPrototype", "untaintedAccessor", "untaintedMethodCache", "getUntaintedMethod", "untaintedMethod", "childNodes", "n", "parentNode", "parentElement", "textContent", "contains", "other", "getRootNode", "host", "styleSheets", "shadowRoot", "querySelector", "selectors", "querySelectorAll", "mutationObserverCtor", "index"]
4
+ "sourcesContent": ["type PrototypeOwner = Node | ShadowRoot | MutationObserver | Element;\ntype TypeofPrototypeOwner =\n | typeof Node\n | typeof ShadowRoot\n | typeof MutationObserver\n | typeof Element;\n\ntype BasePrototypeCache = {\n Node: typeof Node.prototype;\n ShadowRoot: typeof ShadowRoot.prototype;\n MutationObserver: typeof MutationObserver.prototype;\n Element: typeof Element.prototype;\n};\n\nconst testableAccessors = {\n Node: ['childNodes', 'parentNode', 'parentElement', 'textContent'] as const,\n ShadowRoot: ['host', 'styleSheets'] as const,\n Element: ['shadowRoot', 'querySelector', 'querySelectorAll'] as const,\n MutationObserver: [] as const,\n} as const;\n\nconst testableMethods = {\n Node: ['contains', 'getRootNode'] as const,\n ShadowRoot: ['getSelection'],\n Element: [],\n MutationObserver: ['constructor'],\n} as const;\n\nconst untaintedBasePrototype: Partial<BasePrototypeCache> = {};\n\n/*\n When angular patches things - particularly the MutationObserver -\n they pass the `isNativeFunction` check\n That then causes performance issues\n because Angular's change detection\n doesn't like sharing a mutation observer\n Checking for the presence of the Zone object\n on global is a good-enough proxy for Angular\n to cover most cases\n (you can configure zone.js to have a different name\n on the global object and should then manually run rrweb\n outside the Zone)\n */\nexport const isAngularZonePresent = (): boolean => {\n return !!(globalThis as { Zone?: unknown }).Zone;\n};\n\nexport function getUntaintedPrototype<T extends keyof BasePrototypeCache>(\n key: T,\n): BasePrototypeCache[T] {\n if (untaintedBasePrototype[key])\n return untaintedBasePrototype[key] as BasePrototypeCache[T];\n\n const defaultObj = globalThis[key] as TypeofPrototypeOwner;\n const defaultPrototype = defaultObj.prototype as BasePrototypeCache[T];\n\n // use list of testable accessors to check if the prototype is tainted\n const accessorNames =\n key in testableAccessors ? testableAccessors[key] : undefined;\n const isUntaintedAccessors = Boolean(\n accessorNames &&\n // @ts-expect-error 2345\n accessorNames.every((accessor: keyof typeof defaultPrototype) =>\n Boolean(\n Object.getOwnPropertyDescriptor(defaultPrototype, accessor)\n ?.get?.toString()\n .includes('[native code]'),\n ),\n ),\n );\n\n const methodNames = key in testableMethods ? testableMethods[key] : undefined;\n const isUntaintedMethods = Boolean(\n methodNames &&\n methodNames.every(\n // @ts-expect-error 2345\n (method: keyof typeof defaultPrototype) =>\n typeof defaultPrototype[method] === 'function' &&\n defaultPrototype[method]?.toString().includes('[native code]'),\n ),\n );\n\n if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {\n untaintedBasePrototype[key] = defaultObj.prototype as BasePrototypeCache[T];\n return defaultObj.prototype as BasePrototypeCache[T];\n }\n\n try {\n const iframeEl = document.createElement('iframe');\n document.body.appendChild(iframeEl);\n const win = iframeEl.contentWindow;\n if (!win) return defaultObj.prototype as BasePrototypeCache[T];\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n const untaintedObject = (win as any)[key]\n .prototype as BasePrototypeCache[T];\n // cleanup\n document.body.removeChild(iframeEl);\n\n if (!untaintedObject) return defaultPrototype;\n\n return (untaintedBasePrototype[key] = untaintedObject);\n } catch {\n return defaultPrototype;\n }\n}\n\nconst untaintedAccessorCache: Record<\n string,\n (this: PrototypeOwner, ...args: unknown[]) => unknown\n> = {};\n\nexport function getUntaintedAccessor<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n accessor: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(accessor)}`;\n if (untaintedAccessorCache[cacheKey])\n return untaintedAccessorCache[cacheKey].call(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const untaintedAccessor = Object.getOwnPropertyDescriptor(\n untaintedPrototype,\n accessor,\n )?.get;\n\n if (!untaintedAccessor) return instance[accessor];\n\n untaintedAccessorCache[cacheKey] = untaintedAccessor;\n\n return untaintedAccessor.call(instance) as BasePrototypeCache[K][T];\n}\n\ntype BaseMethod<K extends keyof BasePrototypeCache> = (\n this: BasePrototypeCache[K],\n ...args: unknown[]\n) => unknown;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst untaintedMethodCache: Record<string, BaseMethod<any>> = {};\nexport function getUntaintedMethod<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n method: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(method)}`;\n if (untaintedMethodCache[cacheKey])\n return untaintedMethodCache[cacheKey].bind(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n const untaintedMethod = untaintedPrototype[method];\n\n if (typeof untaintedMethod !== 'function') return instance[method];\n\n untaintedMethodCache[cacheKey] = untaintedMethod as BaseMethod<K>;\n\n return untaintedMethod.bind(instance) as BasePrototypeCache[K][T];\n}\n\nexport function childNodes(n: Node): NodeListOf<Node> {\n return getUntaintedAccessor('Node', n, 'childNodes');\n}\n\nexport function parentNode(n: Node): ParentNode | null {\n return getUntaintedAccessor('Node', n, 'parentNode');\n}\n\nexport function parentElement(n: Node): HTMLElement | null {\n return getUntaintedAccessor('Node', n, 'parentElement');\n}\n\nexport function textContent(n: Node): string | null {\n return getUntaintedAccessor('Node', n, 'textContent');\n}\n\nexport function contains(n: Node, other: Node): boolean {\n return getUntaintedMethod('Node', n, 'contains')(other);\n}\n\nexport function getRootNode(n: Node): Node {\n return getUntaintedMethod('Node', n, 'getRootNode')();\n}\n\nexport function host(n: ShadowRoot): Element | null {\n if (!n || !('host' in n)) return null;\n return getUntaintedAccessor('ShadowRoot', n, 'host');\n}\n\nexport function styleSheets(n: ShadowRoot): StyleSheetList {\n return n.styleSheets;\n}\n\nexport function shadowRoot(n: Node): ShadowRoot | null {\n if (!n || !('shadowRoot' in n)) return null;\n return getUntaintedAccessor('Element', n as Element, 'shadowRoot');\n}\n\nexport function querySelector(n: Element, selectors: string): Element | null {\n return getUntaintedAccessor('Element', n, 'querySelector')(selectors);\n}\n\nexport function querySelectorAll(\n n: Element,\n selectors: string,\n): NodeListOf<Element> {\n return getUntaintedAccessor('Element', n, 'querySelectorAll')(selectors);\n}\n\nexport function mutationObserverCtor(): (typeof MutationObserver)['prototype']['constructor'] {\n return getUntaintedPrototype('MutationObserver').constructor;\n}\n\n// copy from https://github.com/getsentry/sentry-javascript/blob/b2109071975af8bf0316d3b5b38f519bdaf5dc15/packages/utils/src/object.ts\nexport function patch(\n source: { [key: string]: any },\n name: string,\n replacement: (...args: unknown[]) => unknown,\n): () => void {\n try {\n if (!(name in source)) {\n return () => {\n //\n };\n }\n\n const original = source[name] as () => unknown;\n const wrapped = replacement(original);\n\n // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work\n // otherwise it'll throw \"TypeError: Object.defineProperties called on non-object\"\n if (typeof wrapped === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n wrapped.prototype = wrapped.prototype || {};\n Object.defineProperties(wrapped, {\n __rrweb_original__: {\n enumerable: false,\n value: original,\n },\n });\n }\n\n source[name] = wrapped;\n\n return () => {\n source[name] = original;\n };\n } catch {\n return () => {\n //\n };\n // This can throw if multiple fill happens on a global object like XMLHttpRequest\n // Fixes https://github.com/getsentry/sentry-javascript/issues/2043\n }\n}\n\nexport default {\n childNodes,\n parentNode,\n parentElement,\n textContent,\n contains,\n getRootNode,\n host,\n styleSheets,\n shadowRoot,\n querySelector,\n querySelectorAll,\n mutationObserver: mutationObserverCtor,\n patch,\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["testableAccessors", "testableMethods", "untaintedBasePrototype", "isAngularZonePresent", "getUntaintedPrototype", "key", "defaultObj", "defaultPrototype", "accessorNames", "isUntaintedAccessors", "accessor", "_b", "_a", "methodNames", "isUntaintedMethods", "method", "iframeEl", "win", "untaintedObject", "e", "untaintedAccessorCache", "getUntaintedAccessor", "instance", "cacheKey", "untaintedPrototype", "untaintedAccessor", "untaintedMethodCache", "getUntaintedMethod", "untaintedMethod", "childNodes", "n", "parentNode", "parentElement", "textContent", "contains", "other", "getRootNode", "host", "styleSheets", "shadowRoot", "querySelector", "selectors", "querySelectorAll", "mutationObserverCtor", "patch", "source", "name", "replacement", "original", "wrapped", "index"]
7
7
  }
package/package.json CHANGED
@@ -1,17 +1,16 @@
1
1
  {
2
2
  "name": "@appsurify-testmap/rrweb-utils",
3
- "version": "2.0.0-alpha.40",
3
+ "version": "2.1.0-alpha.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
7
  "keywords": [
8
8
  "rrweb",
9
- "rrweb-utils"
9
+ "@rrweb/utils"
10
10
  ],
11
11
  "scripts": {
12
12
  "dev": "vite build --watch",
13
13
  "build": "tsc -noEmit && vite build",
14
- "build:tarball": "yarn pack",
15
14
  "check-types": "tsc -noEmit",
16
15
  "prepublish": "npm run build",
17
16
  "lint": "yarn eslint src/**/*.ts"