@posthog/rrweb-snapshot 0.0.48 → 0.0.50

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.
@@ -611,7 +611,9 @@ function slimDOMExcluded(sn, slimDOMOptions) {
611
611
  return true;
612
612
  } else if (slimDOMOptions.headFavicon && (sn.tagName === "link" && sn.attributes.rel === "shortcut icon" || sn.tagName === "meta" && (lowerIfExists(sn.attributes.name).match(
613
613
  /^msapplication-tile(image|color)$/
614
- ) || lowerIfExists(sn.attributes.name) === "application-name" || lowerIfExists(sn.attributes.rel) === "icon" || lowerIfExists(sn.attributes.rel) === "apple-touch-icon" || lowerIfExists(sn.attributes.rel) === "shortcut icon"))) {
614
+ ) || lowerIfExists(sn.attributes.name) === "application-name" || ["icon", "apple-touch-icon", "shortcut icon"].includes(
615
+ lowerIfExists(sn.attributes.rel)
616
+ )))) {
615
617
  return true;
616
618
  } else if (sn.tagName === "meta") {
617
619
  if (slimDOMOptions.headMetaDescKeywords && lowerIfExists(sn.attributes.name).match(/^description|keywords$/)) {
@@ -619,13 +621,25 @@ function slimDOMExcluded(sn, slimDOMOptions) {
619
621
  } else if (slimDOMOptions.headMetaSocial && (lowerIfExists(sn.attributes.property).match(/^(og|twitter|fb):/) || // og = opengraph (facebook)
620
622
  lowerIfExists(sn.attributes.name).match(/^(og|twitter):/) || lowerIfExists(sn.attributes.name) === "pinterest")) {
621
623
  return true;
622
- } else if (slimDOMOptions.headMetaRobots && (lowerIfExists(sn.attributes.name) === "robots" || lowerIfExists(sn.attributes.name) === "googlebot" || lowerIfExists(sn.attributes.name) === "bingbot")) {
624
+ } else if (slimDOMOptions.headMetaRobots && ["robots", "googlebot", "bingbot"].includes(
625
+ lowerIfExists(sn.attributes.name)
626
+ )) {
623
627
  return true;
624
628
  } else if (slimDOMOptions.headMetaHttpEquiv && sn.attributes["http-equiv"] !== void 0) {
625
629
  return true;
626
- } else if (slimDOMOptions.headMetaAuthorship && (lowerIfExists(sn.attributes.name) === "author" || lowerIfExists(sn.attributes.name) === "generator" || lowerIfExists(sn.attributes.name) === "framework" || lowerIfExists(sn.attributes.name) === "publisher" || lowerIfExists(sn.attributes.name) === "progid" || lowerIfExists(sn.attributes.property).match(/^article:/) || lowerIfExists(sn.attributes.property).match(/^product:/))) {
630
+ } else if (slimDOMOptions.headMetaAuthorship && (["author", "generator", "framework", "publisher", "progid"].includes(
631
+ lowerIfExists(sn.attributes.name)
632
+ ) || lowerIfExists(sn.attributes.property).match(/^article:/) || lowerIfExists(sn.attributes.property).match(/^product:/))) {
627
633
  return true;
628
- } else if (slimDOMOptions.headMetaVerification && (lowerIfExists(sn.attributes.name) === "google-site-verification" || lowerIfExists(sn.attributes.name) === "yandex-verification" || lowerIfExists(sn.attributes.name) === "csrf-token" || lowerIfExists(sn.attributes.name) === "p:domain_verify" || lowerIfExists(sn.attributes.name) === "verify-v1" || lowerIfExists(sn.attributes.name) === "verification" || lowerIfExists(sn.attributes.name) === "shopify-checkout-api-token")) {
634
+ } else if (slimDOMOptions.headMetaVerification && [
635
+ "google-site-verification",
636
+ "yandex-verification",
637
+ "csrf-token",
638
+ "p:domain_verify",
639
+ "verify-v1",
640
+ "verification",
641
+ "shopify-checkout-api-token"
642
+ ].includes(lowerIfExists(sn.attributes.name))) {
629
643
  return true;
630
644
  }
631
645
  }
@@ -878,6 +892,27 @@ function serializeNodeWithId(n, options) {
878
892
  }
879
893
  return serializedNode;
880
894
  }
895
+ function slimDOMDefaults(slimDOM) {
896
+ if (slimDOM === true || slimDOM === "all") {
897
+ return {
898
+ script: true,
899
+ comment: true,
900
+ headFavicon: true,
901
+ headWhitespace: true,
902
+ headMetaSocial: true,
903
+ headMetaRobots: true,
904
+ headMetaHttpEquiv: true,
905
+ headMetaVerification: true,
906
+ headMetaAuthorship: slimDOM === "all",
907
+ headMetaDescKeywords: slimDOM === "all",
908
+ headTitleMutations: slimDOM === "all"
909
+ };
910
+ }
911
+ if (slimDOM === false) {
912
+ return {};
913
+ }
914
+ return slimDOM;
915
+ }
881
916
  function snapshot(n, options) {
882
917
  const {
883
918
  mirror = new Mirror(),
@@ -922,22 +957,7 @@ function snapshot(n, options) {
922
957
  } : maskAllInputs === false ? {
923
958
  password: true
924
959
  } : maskAllInputs;
925
- const slimDOMOptions = slimDOM === true || slimDOM === "all" ? (
926
- // if true: set of sensible options that should not throw away any information
927
- {
928
- script: true,
929
- comment: true,
930
- headFavicon: true,
931
- headWhitespace: true,
932
- headMetaDescKeywords: slimDOM === "all",
933
- // destructive
934
- headMetaSocial: true,
935
- headMetaRobots: true,
936
- headMetaHttpEquiv: true,
937
- headMetaAuthorship: true,
938
- headMetaVerification: true
939
- }
940
- ) : slimDOM === false ? {} : slimDOM;
960
+ const slimDOMOptions = slimDOMDefaults(slimDOM);
941
961
  return serializeNodeWithId(n, {
942
962
  doc: n,
943
963
  mirror,
@@ -983,6 +1003,7 @@ export {
983
1003
  serializeNodeWithId as a,
984
1004
  classMatchesRegex as b,
985
1005
  cleanupSnapshot as c,
1006
+ slimDOMDefaults as d,
986
1007
  genId as g,
987
1008
  ignoreAttribute as i,
988
1009
  needMaskingText as n,
@@ -992,4 +1013,4 @@ export {
992
1013
  visitSnapshot as v,
993
1014
  wasMaxDepthReached as w
994
1015
  };
995
- //# sourceMappingURL=record-B2nV9UFB.js.map
1016
+ //# sourceMappingURL=record-CbT7EKn4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-CbT7EKn4.js","sources":["../src/snapshot.ts"],"sourcesContent":["import type {\n MaskInputOptions,\n SlimDOMOptions,\n MaskTextFn,\n MaskInputFn,\n KeepIframeSrcFn,\n ICanvas,\n DialogAttributes,\n} from './types';\nimport { NodeType } from '@posthog/rrweb-types';\nimport type {\n serializedNode,\n serializedNodeWithId,\n serializedElementNodeWithId,\n elementNode,\n attributes,\n mediaAttributes,\n DataURLOptions,\n} from '@posthog/rrweb-types';\nimport {\n Mirror,\n is2DCanvasBlank,\n isElement,\n isShadowRoot,\n maskInputValue,\n isNativeShadowDom,\n stringifyStylesheet,\n getInputType,\n toLowerCase,\n extractFileExtension,\n checkDataURLSize,\n recompressBase64Image,\n absolutifyURLs,\n} from './utils';\nimport dom from '@posthog/rrweb-utils';\n\nlet _id = 1;\nconst tagNameRegex = new RegExp('[^a-z0-9-_:]');\n\nexport const IGNORED_NODE = -2;\n\nexport function genId(): number {\n return _id++;\n}\n\nfunction getValidTagName(element: HTMLElement): Lowercase<string> {\n if (element instanceof HTMLFormElement) {\n return 'form';\n }\n\n const processedTagName = toLowerCase(element.tagName);\n\n if (tagNameRegex.test(processedTagName)) {\n // if the tag name is odd and we cannot extract\n // anything from the string, then we return a\n // generic div\n return 'div';\n }\n\n return processedTagName;\n}\n\nlet canvasService: HTMLCanvasElement | null;\nlet canvasCtx: CanvasRenderingContext2D | null;\n\n// eslint-disable-next-line no-control-regex\nconst SRCSET_NOT_SPACES = /^[^ \\t\\n\\r\\u000c]+/; // Don't use \\s, to avoid matching non-breaking space\n// eslint-disable-next-line no-control-regex\nconst SRCSET_COMMAS_OR_SPACES = /^[, \\t\\n\\r\\u000c]+/;\n\nfunction getAbsoluteSrcsetString(doc: Document, attributeValue: string) {\n /*\n run absoluteToDoc over every url in the srcset\n\n this is adapted from https://github.com/albell/parse-srcset/\n without the parsing of the descriptors (we return these as-is)\n parce-srcset is in turn based on\n https://html.spec.whatwg.org/multipage/embedded-content.html#parse-a-srcset-attribute\n */\n if (attributeValue.trim() === '') {\n return attributeValue;\n }\n\n let pos = 0;\n\n function collectCharacters(regEx: RegExp) {\n let chars: string;\n const match = regEx.exec(attributeValue.substring(pos));\n if (match) {\n chars = match[0];\n pos += chars.length;\n return chars;\n }\n return '';\n }\n\n const output = [];\n // eslint-disable-next-line no-constant-condition\n while (true) {\n collectCharacters(SRCSET_COMMAS_OR_SPACES);\n if (pos >= attributeValue.length) {\n break;\n }\n // don't split on commas within urls\n let url = collectCharacters(SRCSET_NOT_SPACES);\n if (url.slice(-1) === ',') {\n // aside: according to spec more than one comma at the end is a parse error, but we ignore that\n url = absoluteToDoc(doc, url.substring(0, url.length - 1));\n // the trailing comma splits the srcset, so the interpretion is that\n // another url will follow, and the descriptor is empty\n output.push(url);\n } else {\n let descriptorsStr = '';\n url = absoluteToDoc(doc, url);\n let inParens = false;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const c = attributeValue.charAt(pos);\n if (c === '') {\n output.push((url + descriptorsStr).trim());\n break;\n } else if (!inParens) {\n if (c === ',') {\n pos += 1;\n output.push((url + descriptorsStr).trim());\n break; // parse the next url\n } else if (c === '(') {\n inParens = true;\n }\n } else {\n // in parenthesis; ignore commas\n // (parenthesis may be supported by future additions to spec)\n if (c === ')') {\n inParens = false;\n }\n }\n descriptorsStr += c;\n pos += 1;\n }\n }\n }\n return output.join(', ');\n}\n\nconst cachedDocument = new WeakMap<Document, HTMLAnchorElement>();\n\nexport function absoluteToDoc(doc: Document, attributeValue: string): string {\n if (!attributeValue || attributeValue.trim() === '') {\n return attributeValue;\n }\n\n return getHref(doc, attributeValue);\n}\n\nfunction isSVGElement(el: Element): boolean {\n return Boolean(el.tagName === 'svg' || (el as SVGElement).ownerSVGElement);\n}\n\nfunction getHref(doc: Document, customHref?: string) {\n let a = cachedDocument.get(doc);\n if (!a) {\n a = doc.createElement('a');\n cachedDocument.set(doc, a);\n }\n if (!customHref) {\n customHref = '';\n } else if (customHref.startsWith('blob:') || customHref.startsWith('data:')) {\n return customHref;\n }\n // note: using `new URL` is slower. See #1434 or https://jsbench.me/uqlud17rxo/1\n a.setAttribute('href', customHref);\n return a.href;\n}\n\nexport function transformAttribute(\n doc: Document,\n tagName: Lowercase<string>,\n name: Lowercase<string>,\n value: string | null,\n element?: HTMLElement,\n dataURLOptions?: DataURLOptions,\n): string | null {\n if (!value) {\n return value;\n }\n\n // relative path in attribute\n if (\n name === 'src' ||\n (name === 'href' && !(tagName === 'use' && value[0] === '#'))\n ) {\n // href starts with a # is an id pointer for svg\n const transformedValue = absoluteToDoc(doc, value);\n\n if (tagName === 'img' && transformedValue.startsWith('data:') && element) {\n const img = element as HTMLImageElement;\n\n let processedDataURL = transformedValue;\n\n if (dataURLOptions?.type || dataURLOptions?.quality !== undefined) {\n processedDataURL = recompressBase64Image(\n img,\n transformedValue,\n dataURLOptions.type,\n dataURLOptions.quality,\n );\n }\n\n if (dataURLOptions?.maxBase64ImageLength) {\n processedDataURL = checkDataURLSize(\n processedDataURL,\n dataURLOptions.maxBase64ImageLength,\n );\n }\n\n return processedDataURL;\n }\n\n return transformedValue;\n } else if (name === 'xlink:href' && value[0] !== '#') {\n // xlink:href starts with # is an id pointer\n return absoluteToDoc(doc, value);\n } else if (\n name === 'background' &&\n (tagName === 'table' || tagName === 'td' || tagName === 'th')\n ) {\n return absoluteToDoc(doc, value);\n } else if (name === 'srcset') {\n return getAbsoluteSrcsetString(doc, value);\n } else if (name === 'style') {\n return absolutifyURLs(value, getHref(doc));\n } else if (tagName === 'object' && name === 'data') {\n return absoluteToDoc(doc, value);\n }\n\n return value;\n}\n\nexport function ignoreAttribute(\n tagName: string,\n name: string,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _value: unknown,\n): boolean {\n return (tagName === 'video' || tagName === 'audio') && name === 'autoplay';\n}\n\nexport function _isBlockedElement(\n element: HTMLElement,\n blockClass: string | RegExp,\n blockSelector: string | null,\n): boolean {\n try {\n if (typeof blockClass === 'string') {\n if (element.classList.contains(blockClass)) {\n return true;\n }\n } else {\n for (let eIndex = element.classList.length; eIndex--; ) {\n const className = element.classList[eIndex];\n if (blockClass.test(className)) {\n return true;\n }\n }\n }\n if (blockSelector) {\n return element.matches(blockSelector);\n }\n } catch (e) {\n //\n }\n\n return false;\n}\n\nexport function classMatchesRegex(\n node: Node | null,\n regex: RegExp,\n checkAncestors: boolean,\n): boolean {\n if (!node) return false;\n if (node.nodeType !== node.ELEMENT_NODE) {\n if (!checkAncestors) return false;\n return classMatchesRegex(dom.parentNode(node), regex, checkAncestors);\n }\n\n for (let eIndex = (node as HTMLElement).classList.length; eIndex--; ) {\n const className = (node as HTMLElement).classList[eIndex];\n if (regex.test(className)) {\n return true;\n }\n }\n if (!checkAncestors) return false;\n return classMatchesRegex(dom.parentNode(node), regex, checkAncestors);\n}\n\nexport function needMaskingText(\n node: Node,\n maskTextClass: string | RegExp,\n maskTextSelector: string | null,\n checkAncestors: boolean,\n): boolean {\n let el: Element;\n if (isElement(node)) {\n el = node;\n if (!dom.childNodes(el).length) {\n // optimisation: we can avoid any of the below checks on leaf elements\n // as masking is applied to child text nodes only\n return false;\n }\n } else if (dom.parentElement(node) === null) {\n // should warn? maybe a text node isn't attached to a parent node yet?\n return false;\n } else {\n el = dom.parentElement(node)!;\n }\n try {\n if (typeof maskTextClass === 'string') {\n if (checkAncestors) {\n if (el.closest(`.${maskTextClass}`)) return true;\n } else {\n if (el.classList.contains(maskTextClass)) return true;\n }\n } else {\n if (classMatchesRegex(el, maskTextClass, checkAncestors)) return true;\n }\n if (maskTextSelector) {\n if (checkAncestors) {\n if (el.closest(maskTextSelector)) return true;\n } else {\n if (el.matches(maskTextSelector)) return true;\n }\n }\n } catch (e) {\n //\n }\n return false;\n}\n\n// https://stackoverflow.com/a/36155560\nfunction onceIframeLoaded(\n iframeEl: HTMLIFrameElement,\n listener: () => unknown,\n iframeLoadTimeout: number,\n) {\n const win = iframeEl.contentWindow;\n if (!win) {\n return;\n }\n // document is loading\n let fired = false;\n\n let readyState: DocumentReadyState;\n try {\n readyState = win.document.readyState;\n } catch (error) {\n return;\n }\n if (readyState !== 'complete') {\n const timer = setTimeout(() => {\n if (!fired) {\n listener();\n fired = true;\n }\n }, iframeLoadTimeout);\n iframeEl.addEventListener('load', () => {\n clearTimeout(timer);\n fired = true;\n listener();\n });\n return;\n }\n // check blank frame for Chrome\n const blankUrl = 'about:blank';\n if (\n win.location.href !== blankUrl ||\n iframeEl.src === blankUrl ||\n iframeEl.src === ''\n ) {\n // iframe was already loaded, make sure we wait to trigger the listener\n // till _after_ the mutation that found this iframe has had time to process\n setTimeout(listener, 0);\n\n return iframeEl.addEventListener('load', listener); // keep listing for future loads\n }\n // use default listener\n iframeEl.addEventListener('load', listener);\n}\n\nfunction onceStylesheetLoaded(\n link: HTMLLinkElement,\n listener: () => unknown,\n styleSheetLoadTimeout: number,\n) {\n let fired = false;\n let styleSheetLoaded: StyleSheet | null;\n try {\n styleSheetLoaded = link.sheet;\n } catch (error) {\n return;\n }\n\n if (styleSheetLoaded) return;\n\n const timer = setTimeout(() => {\n if (!fired) {\n listener();\n fired = true;\n }\n }, styleSheetLoadTimeout);\n\n link.addEventListener('load', () => {\n clearTimeout(timer);\n fired = true;\n listener();\n });\n}\n\nfunction serializeNode(\n n: Node,\n options: {\n doc: Document;\n mirror: Mirror;\n blockClass: string | RegExp;\n blockSelector: string | null;\n needsMask: boolean;\n inlineStylesheet: boolean;\n maskInputOptions: MaskInputOptions;\n maskTextFn: MaskTextFn | undefined;\n maskInputFn: MaskInputFn | undefined;\n dataURLOptions?: DataURLOptions;\n inlineImages: boolean;\n recordCanvas: boolean;\n keepIframeSrcFn: KeepIframeSrcFn;\n /**\n * `newlyAddedElement: true` skips scrollTop and scrollLeft check\n */\n newlyAddedElement?: boolean;\n },\n): serializedNode | false {\n const {\n doc,\n mirror,\n blockClass,\n blockSelector,\n needsMask,\n inlineStylesheet,\n maskInputOptions = {},\n maskTextFn,\n maskInputFn,\n dataURLOptions = {},\n inlineImages,\n recordCanvas,\n keepIframeSrcFn,\n newlyAddedElement = false,\n } = options;\n // Only record root id when document object is not the base document\n const rootId = getRootId(doc, mirror);\n switch (n.nodeType) {\n case n.DOCUMENT_NODE:\n if ((n as Document).compatMode !== 'CSS1Compat') {\n return {\n type: NodeType.Document,\n childNodes: [],\n compatMode: (n as Document).compatMode, // probably \"BackCompat\"\n };\n } else {\n return {\n type: NodeType.Document,\n childNodes: [],\n };\n }\n case n.DOCUMENT_TYPE_NODE:\n return {\n type: NodeType.DocumentType,\n name: (n as DocumentType).name,\n publicId: (n as DocumentType).publicId,\n systemId: (n as DocumentType).systemId,\n rootId,\n };\n case n.ELEMENT_NODE:\n return serializeElementNode(n as HTMLElement, {\n doc,\n blockClass,\n blockSelector,\n inlineStylesheet,\n maskInputOptions,\n maskInputFn,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n keepIframeSrcFn,\n newlyAddedElement,\n rootId,\n });\n case n.TEXT_NODE:\n return serializeTextNode(n as Text, {\n doc,\n needsMask,\n maskTextFn,\n rootId,\n });\n case n.CDATA_SECTION_NODE:\n return {\n type: NodeType.CDATA,\n textContent: '',\n rootId,\n };\n case n.COMMENT_NODE:\n return {\n type: NodeType.Comment,\n textContent: dom.textContent(n as Comment) || '',\n rootId,\n };\n default:\n return false;\n }\n}\n\nfunction getRootId(doc: Document, mirror: Mirror): number | undefined {\n if (!mirror.hasNode(doc)) return undefined;\n const docId = mirror.getId(doc);\n return docId === 1 ? undefined : docId;\n}\n\nfunction serializeTextNode(\n n: Text,\n options: {\n doc: Document;\n needsMask: boolean;\n maskTextFn: MaskTextFn | undefined;\n rootId: number | undefined;\n },\n): serializedNode {\n const { needsMask, maskTextFn, rootId } = options;\n // The parent node may not be a html element which has a tagName attribute.\n // So just let it be undefined which is ok in this use case.\n const parent = dom.parentNode(n);\n const parentTagName = parent && (parent as HTMLElement).tagName;\n let text = dom.textContent(n);\n const isStyle = parentTagName === 'STYLE' ? true : undefined;\n const isScript = parentTagName === 'SCRIPT' ? true : undefined;\n if (isStyle && text) {\n try {\n // try to read style sheet\n if (n.nextSibling || n.previousSibling) {\n // This is not the only child of the stylesheet.\n // We can't read all of the sheet's .cssRules and expect them\n // to _only_ include the current rule(s) added by the text node.\n // So we'll be conservative and keep textContent as-is.\n } else if ((parent as HTMLStyleElement).sheet?.cssRules) {\n text = stringifyStylesheet((parent as HTMLStyleElement).sheet!);\n }\n } catch (err) {\n console.warn(\n `Cannot get CSS styles from text's parentNode. Error: ${err as string}`,\n n,\n );\n }\n text = absolutifyURLs(text, getHref(options.doc));\n }\n if (isScript) {\n text = 'SCRIPT_PLACEHOLDER';\n }\n if (!isStyle && !isScript && text && needsMask) {\n text = maskTextFn\n ? maskTextFn(text, dom.parentElement(n))\n : text.replace(/[\\S]/g, '*');\n }\n\n return {\n type: NodeType.Text,\n textContent: text || '',\n isStyle,\n rootId,\n };\n}\n\nfunction findStylesheet(doc: Document, href: string) {\n return Array.from(doc.styleSheets).find((s) => s.href === href);\n}\n\n/**\n * in production, we've seen elements like\n * `<link type=\"text/css\" rel=\"stylesheet\" id=\"dark-mode-custom-link\"></link>`\n * while HTMLLinkElement suggests an href is always present\n * the w3c spec is less specific\n * and regardless we've seen at least one instance of this in the wild\n * let's be defensive and make sure this is typed as possibly undefined\n */\nfunction hrefFrom(n: unknown): string | undefined {\n return (n as HTMLLinkElement).href;\n}\n\nfunction serializeElementNode(\n n: HTMLElement,\n options: {\n doc: Document;\n blockClass: string | RegExp;\n blockSelector: string | null;\n inlineStylesheet: boolean;\n maskInputOptions: MaskInputOptions;\n maskInputFn: MaskInputFn | undefined;\n dataURLOptions?: DataURLOptions;\n inlineImages: boolean;\n recordCanvas: boolean;\n keepIframeSrcFn: KeepIframeSrcFn;\n /**\n * `newlyAddedElement: true` skips scrollTop and scrollLeft check\n */\n newlyAddedElement?: boolean;\n rootId: number | undefined;\n },\n): serializedNode | false {\n const {\n doc,\n blockClass,\n blockSelector,\n inlineStylesheet,\n maskInputOptions = {},\n maskInputFn,\n dataURLOptions = {},\n inlineImages,\n recordCanvas,\n keepIframeSrcFn,\n newlyAddedElement = false,\n rootId,\n } = options;\n const needBlock = _isBlockedElement(n, blockClass, blockSelector);\n const tagName = getValidTagName(n);\n let attributes: attributes = {};\n const len = n.attributes.length;\n for (let i = 0; i < len; i++) {\n const attr = n.attributes[i];\n if (!ignoreAttribute(tagName, attr.name, attr.value)) {\n attributes[attr.name] = transformAttribute(\n doc,\n tagName,\n toLowerCase(attr.name),\n attr.value,\n n,\n dataURLOptions,\n );\n }\n }\n // remote css\n if (tagName === 'link' && inlineStylesheet) {\n //TODO: maybe replace this `.styleSheets` with original one\n const href: string | undefined = hrefFrom(n);\n if (href) {\n let stylesheet = findStylesheet(doc, href);\n if (!stylesheet && href.includes('.css')) {\n const rootDomain = window.location.origin;\n const stylesheetPath = href.replace(window.location.href, '');\n const potentialStylesheetHref = rootDomain + '/' + stylesheetPath;\n stylesheet = findStylesheet(doc, potentialStylesheetHref);\n }\n let cssText: string | null = null;\n if (stylesheet) {\n cssText = stringifyStylesheet(stylesheet);\n }\n if (cssText) {\n delete attributes.rel;\n delete attributes.href;\n attributes._cssText = cssText;\n }\n }\n }\n // dynamic stylesheet\n if (\n tagName === 'style' &&\n (n as HTMLStyleElement).sheet &&\n // TODO: Currently we only try to get dynamic stylesheet when it is an empty style element\n !(n.innerText || dom.textContent(n) || '').trim().length\n ) {\n const cssText = stringifyStylesheet(\n (n as HTMLStyleElement).sheet as CSSStyleSheet,\n );\n if (cssText) {\n attributes._cssText = cssText;\n }\n }\n // form fields\n if (tagName === 'input' || tagName === 'textarea' || tagName === 'select') {\n const value = (n as HTMLInputElement | HTMLTextAreaElement).value;\n const checked = (n as HTMLInputElement).checked;\n if (\n attributes.type !== 'radio' &&\n attributes.type !== 'checkbox' &&\n attributes.type !== 'submit' &&\n attributes.type !== 'button' &&\n value\n ) {\n attributes.value = maskInputValue({\n element: n,\n type: getInputType(n),\n tagName,\n value,\n maskInputOptions,\n maskInputFn,\n });\n } else if (checked) {\n attributes.checked = checked;\n }\n }\n if (tagName === 'option') {\n if ((n as HTMLOptionElement).selected && !maskInputOptions['select']) {\n attributes.selected = true;\n } else {\n // ignore the html attribute (which corresponds to DOM (n as HTMLOptionElement).defaultSelected)\n // if it's already been changed\n delete attributes.selected;\n }\n }\n\n if (tagName === 'dialog' && (n as HTMLDialogElement).open) {\n // register what type of dialog is this\n // `modal` or `non-modal`\n // this is used to trigger `showModal()` or `show()` on replay (outside of rrweb-snapshot, in rrweb)\n try {\n (attributes as DialogAttributes).rr_open_mode = n.matches('dialog:modal')\n ? 'modal'\n : 'non-modal';\n } catch {\n // likely this is safari not able to deal with the `:modal` selector\n // we can't detect whether the dialog is modal or non-modal open, so have to guess\n // hopefully this is only safari 15.4 and 15.5\n attributes.rr_open_mode = 'modal';\n attributes.ph_rr_could_not_detect_modal = true;\n }\n }\n\n // canvas image data\n if (tagName === 'canvas' && recordCanvas) {\n if ((n as ICanvas).__context === '2d') {\n // only record this on 2d canvas\n if (!is2DCanvasBlank(n as HTMLCanvasElement)) {\n attributes.rr_dataURL = (n as HTMLCanvasElement).toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality,\n );\n }\n } else if (!('__context' in n)) {\n // context is unknown, better not call getContext to trigger it\n const canvasDataURL = (n as HTMLCanvasElement).toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality,\n );\n\n // create blank canvas of same dimensions\n const blankCanvas = doc.createElement('canvas');\n blankCanvas.width = (n as HTMLCanvasElement).width;\n blankCanvas.height = (n as HTMLCanvasElement).height;\n const blankCanvasDataURL = blankCanvas.toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality,\n );\n\n // no need to save dataURL if it's the same as blank canvas\n if (canvasDataURL !== blankCanvasDataURL) {\n attributes.rr_dataURL = canvasDataURL;\n }\n }\n }\n // save image offline\n if (tagName === 'img' && inlineImages) {\n if (!canvasService) {\n canvasService = doc.createElement('canvas');\n canvasCtx = canvasService.getContext('2d');\n }\n const image = n as HTMLImageElement;\n const imageSrc: string =\n image.currentSrc || image.getAttribute('src') || '<unknown-src>';\n const priorCrossOrigin = image.crossOrigin;\n const recordInlineImage = () => {\n image.removeEventListener('load', recordInlineImage);\n try {\n canvasService!.width = image.naturalWidth;\n canvasService!.height = image.naturalHeight;\n canvasCtx!.drawImage(image, 0, 0);\n attributes.rr_dataURL = canvasService!.toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality,\n );\n } catch (err) {\n if (image.crossOrigin !== 'anonymous') {\n image.crossOrigin = 'anonymous';\n if (image.complete && image.naturalWidth !== 0)\n recordInlineImage(); // too early due to image reload\n else image.addEventListener('load', recordInlineImage);\n return;\n } else {\n console.warn(\n `Cannot inline img src=${imageSrc}! Error: ${err as string}`,\n );\n }\n }\n if (image.crossOrigin === 'anonymous') {\n priorCrossOrigin\n ? (attributes.crossOrigin = priorCrossOrigin)\n : image.removeAttribute('crossorigin');\n }\n };\n // The image content may not have finished loading yet.\n if (image.complete && image.naturalWidth !== 0) recordInlineImage();\n else image.addEventListener('load', recordInlineImage);\n }\n // media elements\n if (tagName === 'audio' || tagName === 'video') {\n const mediaAttributes = attributes as mediaAttributes;\n mediaAttributes.rr_mediaState = (n as HTMLMediaElement).paused\n ? 'paused'\n : 'played';\n mediaAttributes.rr_mediaCurrentTime = (n as HTMLMediaElement).currentTime;\n mediaAttributes.rr_mediaPlaybackRate = (n as HTMLMediaElement).playbackRate;\n mediaAttributes.rr_mediaMuted = (n as HTMLMediaElement).muted;\n mediaAttributes.rr_mediaLoop = (n as HTMLMediaElement).loop;\n mediaAttributes.rr_mediaVolume = (n as HTMLMediaElement).volume;\n }\n // Scroll\n if (!newlyAddedElement) {\n // `scrollTop` and `scrollLeft` are expensive calls because they trigger reflow.\n // Since `scrollTop` & `scrollLeft` are always 0 when an element is added to the DOM.\n // And scrolls also get picked up by rrweb's ScrollObserver\n // So we can safely skip the `scrollTop/Left` calls for newly added elements\n if (n.scrollLeft) {\n attributes.rr_scrollLeft = n.scrollLeft;\n }\n if (n.scrollTop) {\n attributes.rr_scrollTop = n.scrollTop;\n }\n }\n // block element\n if (needBlock) {\n const { width, height, left, top } = n.getBoundingClientRect();\n attributes = {\n class: attributes.class,\n rr_width: `${width}px`,\n rr_height: `${height}px`,\n rr_left: `${Math.floor(left + (doc.defaultView?.scrollX || 0))}px`,\n rr_top: `${Math.floor(top + (doc.defaultView?.scrollY || 0))}px`,\n };\n }\n // iframe\n if (tagName === 'iframe' && !keepIframeSrcFn(attributes.src as string)) {\n if (!(n as HTMLIFrameElement).contentDocument) {\n // we can't record it directly as we can't see into it\n // preserve the src attribute so a decision can be taken at replay time\n attributes.rr_src = attributes.src;\n }\n delete attributes.src; // prevent auto loading\n }\n\n let isCustomElement: true | undefined;\n try {\n if (customElements.get(tagName)) isCustomElement = true;\n } catch (e) {\n // In case old browsers don't support customElements\n }\n\n return {\n type: NodeType.Element,\n tagName,\n attributes,\n childNodes: [],\n isSVG: isSVGElement(n as Element) || undefined,\n needBlock,\n rootId,\n isCustom: isCustomElement,\n };\n}\n\nfunction lowerIfExists(\n maybeAttr: string | number | boolean | undefined | null,\n): string {\n if (maybeAttr === undefined || maybeAttr === null) {\n return '';\n } else {\n return (maybeAttr as string).toLowerCase();\n }\n}\n\nfunction slimDOMExcluded(\n sn: serializedNode,\n slimDOMOptions: SlimDOMOptions,\n): boolean {\n if (slimDOMOptions.comment && sn.type === NodeType.Comment) {\n // TODO: convert IE conditional comments to real nodes\n return true;\n } else if (sn.type === NodeType.Element) {\n if (\n slimDOMOptions.script &&\n // script tag\n (sn.tagName === 'script' ||\n // (module)preload link\n (sn.tagName === 'link' &&\n ((sn.attributes.rel === 'preload' && sn.attributes.as === 'script') ||\n sn.attributes.rel === 'modulepreload')) ||\n // prefetch link\n (sn.tagName === 'link' &&\n sn.attributes.rel === 'prefetch' &&\n typeof sn.attributes.href === 'string' &&\n extractFileExtension(sn.attributes.href) === 'js'))\n ) {\n return true;\n } else if (\n slimDOMOptions.headFavicon &&\n ((sn.tagName === 'link' && sn.attributes.rel === 'shortcut icon') ||\n (sn.tagName === 'meta' &&\n (lowerIfExists(sn.attributes.name).match(\n /^msapplication-tile(image|color)$/,\n ) ||\n lowerIfExists(sn.attributes.name) === 'application-name' ||\n ['icon', 'apple-touch-icon', 'shortcut icon'].includes(\n lowerIfExists(sn.attributes.rel),\n ))))\n ) {\n return true;\n } else if (sn.tagName === 'meta') {\n if (\n slimDOMOptions.headMetaDescKeywords &&\n lowerIfExists(sn.attributes.name).match(/^description|keywords$/)\n ) {\n return true;\n } else if (\n slimDOMOptions.headMetaSocial &&\n (lowerIfExists(sn.attributes.property).match(/^(og|twitter|fb):/) || // og = opengraph (facebook)\n lowerIfExists(sn.attributes.name).match(/^(og|twitter):/) ||\n lowerIfExists(sn.attributes.name) === 'pinterest')\n ) {\n return true;\n } else if (\n slimDOMOptions.headMetaRobots &&\n ['robots', 'googlebot', 'bingbot'].includes(\n lowerIfExists(sn.attributes.name),\n )\n ) {\n return true;\n } else if (\n slimDOMOptions.headMetaHttpEquiv &&\n sn.attributes['http-equiv'] !== undefined\n ) {\n // e.g. X-UA-Compatible, Content-Type, Content-Language,\n // cache-control, X-Translated-By\n return true;\n } else if (\n slimDOMOptions.headMetaAuthorship &&\n (['author', 'generator', 'framework', 'publisher', 'progid'].includes(\n lowerIfExists(sn.attributes.name),\n ) ||\n lowerIfExists(sn.attributes.property).match(/^article:/) ||\n lowerIfExists(sn.attributes.property).match(/^product:/))\n ) {\n return true;\n } else if (\n slimDOMOptions.headMetaVerification &&\n [\n 'google-site-verification',\n 'yandex-verification',\n 'csrf-token',\n 'p:domain_verify',\n 'verify-v1',\n 'verification',\n 'shopify-checkout-api-token',\n ].includes(lowerIfExists(sn.attributes.name))\n ) {\n return true;\n }\n }\n }\n return false;\n}\n\nexport const DEFAULT_MAX_DEPTH = 50;\n\nlet _maxDepthWarned = false;\nlet _maxDepthReached = false;\n\nexport function wasMaxDepthReached(): boolean {\n return _maxDepthReached;\n}\n\nexport function resetMaxDepthState(): void {\n _maxDepthReached = false;\n _maxDepthWarned = false;\n}\n\nexport function serializeNodeWithId(\n n: Node,\n options: {\n doc: Document;\n mirror: Mirror;\n blockClass: string | RegExp;\n blockSelector: string | null;\n maskTextClass: string | RegExp;\n maskTextSelector: string | null;\n skipChild: boolean;\n inlineStylesheet: boolean;\n newlyAddedElement?: boolean;\n maskInputOptions?: MaskInputOptions;\n needsMask?: boolean;\n maskTextFn: MaskTextFn | undefined;\n maskInputFn: MaskInputFn | undefined;\n slimDOMOptions: SlimDOMOptions;\n dataURLOptions?: DataURLOptions;\n keepIframeSrcFn?: KeepIframeSrcFn;\n inlineImages?: boolean;\n recordCanvas?: boolean;\n preserveWhiteSpace?: boolean;\n onSerialize?: (n: Node) => unknown;\n onIframeLoad?: (\n iframeNode: HTMLIFrameElement,\n node: serializedElementNodeWithId,\n ) => unknown;\n iframeLoadTimeout?: number;\n onStylesheetLoad?: (\n linkNode: HTMLLinkElement,\n node: serializedElementNodeWithId,\n ) => unknown;\n stylesheetLoadTimeout?: number;\n depth?: number;\n maxDepth?: number;\n onMaxDepthReached?: () => void;\n },\n): serializedNodeWithId | null {\n const {\n doc,\n mirror,\n blockClass,\n blockSelector,\n maskTextClass,\n maskTextSelector,\n skipChild = false,\n inlineStylesheet = true,\n maskInputOptions = {},\n maskTextFn,\n maskInputFn,\n slimDOMOptions,\n dataURLOptions = {},\n inlineImages = false,\n recordCanvas = false,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout = 5000,\n onStylesheetLoad,\n stylesheetLoadTimeout = 5000,\n keepIframeSrcFn = () => false,\n newlyAddedElement = false,\n depth = 0,\n maxDepth = DEFAULT_MAX_DEPTH,\n } = options;\n let { needsMask } = options;\n let { preserveWhiteSpace = true } = options;\n\n if (depth >= maxDepth) {\n _maxDepthReached = true;\n if (!_maxDepthWarned) {\n _maxDepthWarned = true;\n console.warn(\n `[rrweb-snapshot] DOM tree depth exceeded max depth of ${maxDepth}. ` +\n `Children beyond this depth will not be recorded. ` +\n `This may indicate deeply nested DOM structures.`,\n );\n }\n return null;\n }\n\n if (!needsMask) {\n // perf: if needsMask = true, children won't also need to check\n const checkAncestors = needsMask === undefined; // if false, we've already checked ancestors\n needsMask = needMaskingText(\n n as Element,\n maskTextClass,\n maskTextSelector,\n checkAncestors,\n );\n }\n\n const _serializedNode = serializeNode(n, {\n doc,\n mirror,\n blockClass,\n blockSelector,\n needsMask,\n inlineStylesheet,\n maskInputOptions,\n maskTextFn,\n maskInputFn,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n keepIframeSrcFn,\n newlyAddedElement,\n });\n if (!_serializedNode) {\n // TODO: dev only\n console.warn(n, 'not serialized');\n return null;\n }\n\n let id: number | undefined;\n if (mirror.hasNode(n)) {\n // Reuse the previous id\n id = mirror.getId(n);\n } else if (\n slimDOMExcluded(_serializedNode, slimDOMOptions) ||\n (!preserveWhiteSpace &&\n _serializedNode.type === NodeType.Text &&\n !_serializedNode.isStyle &&\n !_serializedNode.textContent.replace(/^\\s+|\\s+$/gm, '').length)\n ) {\n id = IGNORED_NODE;\n } else {\n id = genId();\n }\n\n const serializedNode = Object.assign(_serializedNode, { id });\n // add IGNORED_NODE to mirror to track nextSiblings\n mirror.add(n, serializedNode);\n\n if (id === IGNORED_NODE) {\n return null; // slimDOM\n }\n\n if (onSerialize) {\n onSerialize(n);\n }\n let recordChild = !skipChild;\n if (serializedNode.type === NodeType.Element) {\n recordChild = recordChild && !serializedNode.needBlock;\n // this property was not needed in replay side\n delete serializedNode.needBlock;\n const shadowRootEl = dom.shadowRoot(n);\n if (shadowRootEl && isNativeShadowDom(shadowRootEl))\n serializedNode.isShadowHost = true;\n }\n if (\n (serializedNode.type === NodeType.Document ||\n serializedNode.type === NodeType.Element) &&\n recordChild\n ) {\n if (\n slimDOMOptions.headWhitespace &&\n serializedNode.type === NodeType.Element &&\n serializedNode.tagName === 'head'\n // would impede performance: || getComputedStyle(n)['white-space'] === 'normal'\n ) {\n preserveWhiteSpace = false;\n }\n const bypassOptions = {\n doc,\n mirror,\n blockClass,\n blockSelector,\n needsMask,\n maskTextClass,\n maskTextSelector,\n skipChild,\n inlineStylesheet,\n maskInputOptions,\n maskTextFn,\n maskInputFn,\n slimDOMOptions,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n depth: depth + 1,\n maxDepth,\n };\n\n if (\n serializedNode.type === NodeType.Element &&\n serializedNode.tagName === 'textarea' &&\n (serializedNode as elementNode).attributes.value !== undefined\n ) {\n // value parameter in DOM reflects the correct value, so ignore childNode\n } else {\n for (const childN of Array.from(dom.childNodes(n))) {\n const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\n if (serializedChildNode) {\n serializedNode.childNodes.push(serializedChildNode);\n }\n }\n }\n\n let shadowRootEl: ShadowRoot | null = null;\n if (isElement(n) && (shadowRootEl = dom.shadowRoot(n))) {\n for (const childN of Array.from(dom.childNodes(shadowRootEl))) {\n const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\n if (serializedChildNode) {\n isNativeShadowDom(shadowRootEl) &&\n (serializedChildNode.isShadow = true);\n serializedNode.childNodes.push(serializedChildNode);\n }\n }\n }\n }\n\n const parent = dom.parentNode(n);\n if (parent && isShadowRoot(parent) && isNativeShadowDom(parent)) {\n serializedNode.isShadow = true;\n }\n\n if (\n serializedNode.type === NodeType.Element &&\n serializedNode.tagName === 'iframe'\n ) {\n onceIframeLoaded(\n n as HTMLIFrameElement,\n () => {\n const iframeDoc = (n as HTMLIFrameElement).contentDocument;\n if (iframeDoc && onIframeLoad) {\n const serializedIframeNode = serializeNodeWithId(iframeDoc, {\n doc: iframeDoc,\n mirror,\n blockClass,\n blockSelector,\n needsMask,\n maskTextClass,\n maskTextSelector,\n skipChild: false,\n inlineStylesheet,\n maskInputOptions,\n maskTextFn,\n maskInputFn,\n slimDOMOptions,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n depth: depth + 1,\n maxDepth,\n });\n\n if (serializedIframeNode) {\n onIframeLoad(\n n as HTMLIFrameElement,\n serializedIframeNode as serializedElementNodeWithId,\n );\n }\n }\n },\n iframeLoadTimeout,\n );\n }\n\n // <link rel=stylesheet href=...>\n if (\n serializedNode.type === NodeType.Element &&\n serializedNode.tagName === 'link' &&\n typeof serializedNode.attributes.rel === 'string' &&\n (serializedNode.attributes.rel === 'stylesheet' ||\n (serializedNode.attributes.rel === 'preload' &&\n typeof serializedNode.attributes.href === 'string' &&\n extractFileExtension(serializedNode.attributes.href) === 'css'))\n ) {\n onceStylesheetLoaded(\n n as HTMLLinkElement,\n () => {\n if (onStylesheetLoad) {\n const serializedLinkNode = serializeNodeWithId(n, {\n doc,\n mirror,\n blockClass,\n blockSelector,\n needsMask,\n maskTextClass,\n maskTextSelector,\n skipChild: false,\n inlineStylesheet,\n maskInputOptions,\n maskTextFn,\n maskInputFn,\n slimDOMOptions,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n depth,\n maxDepth,\n });\n\n if (serializedLinkNode) {\n onStylesheetLoad(\n n as HTMLLinkElement,\n serializedLinkNode as serializedElementNodeWithId,\n );\n }\n }\n },\n stylesheetLoadTimeout,\n );\n }\n\n return serializedNode;\n}\n\nexport function slimDOMDefaults(\n slimDOM: 'all' | boolean | SlimDOMOptions,\n): SlimDOMOptions {\n if (slimDOM === true || slimDOM === 'all') {\n return {\n script: true,\n comment: true,\n headFavicon: true,\n headWhitespace: true,\n headMetaSocial: true,\n headMetaRobots: true,\n headMetaHttpEquiv: true,\n headMetaVerification: true,\n headMetaAuthorship: slimDOM === 'all',\n headMetaDescKeywords: slimDOM === 'all',\n headTitleMutations: slimDOM === 'all',\n };\n }\n if (slimDOM === false) {\n return {};\n }\n return slimDOM;\n}\n\nfunction snapshot(\n n: Document,\n options?: {\n mirror?: Mirror;\n blockClass?: string | RegExp;\n blockSelector?: string | null;\n maskTextClass?: string | RegExp;\n maskTextSelector?: string | null;\n inlineStylesheet?: boolean;\n maskAllInputs?: boolean | MaskInputOptions;\n maskTextFn?: MaskTextFn;\n maskInputFn?: MaskInputFn;\n slimDOM?: 'all' | boolean | SlimDOMOptions;\n dataURLOptions?: DataURLOptions;\n inlineImages?: boolean;\n recordCanvas?: boolean;\n preserveWhiteSpace?: boolean;\n onSerialize?: (n: Node) => unknown;\n onIframeLoad?: (\n iframeNode: HTMLIFrameElement,\n node: serializedElementNodeWithId,\n ) => unknown;\n iframeLoadTimeout?: number;\n onStylesheetLoad?: (\n linkNode: HTMLLinkElement,\n node: serializedElementNodeWithId,\n ) => unknown;\n stylesheetLoadTimeout?: number;\n keepIframeSrcFn?: KeepIframeSrcFn;\n maxDepth?: number;\n },\n): serializedNodeWithId | null {\n const {\n mirror = new Mirror(),\n blockClass = 'rr-block',\n blockSelector = null,\n maskTextClass = 'rr-mask',\n maskTextSelector = null,\n inlineStylesheet = true,\n inlineImages = false,\n recordCanvas = false,\n maskAllInputs = false,\n maskTextFn,\n maskInputFn,\n slimDOM = false,\n dataURLOptions,\n preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn = () => false,\n maxDepth,\n } = options || {};\n const maskInputOptions: MaskInputOptions =\n maskAllInputs === true\n ? {\n color: true,\n date: true,\n 'datetime-local': true,\n email: true,\n month: true,\n number: true,\n range: true,\n search: true,\n tel: true,\n text: true,\n time: true,\n url: true,\n week: true,\n textarea: true,\n select: true,\n password: true,\n }\n : maskAllInputs === false\n ? {\n password: true,\n }\n : maskAllInputs;\n const slimDOMOptions: SlimDOMOptions = slimDOMDefaults(slimDOM);\n return serializeNodeWithId(n, {\n doc: n,\n mirror,\n blockClass,\n blockSelector,\n maskTextClass,\n maskTextSelector,\n skipChild: false,\n inlineStylesheet,\n maskInputOptions,\n maskTextFn,\n maskInputFn,\n slimDOMOptions,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n newlyAddedElement: false,\n maxDepth,\n });\n}\n\nexport function visitSnapshot(\n node: serializedNodeWithId,\n onVisit: (node: serializedNodeWithId) => unknown,\n) {\n function walk(current: serializedNodeWithId) {\n onVisit(current);\n if (\n current.type === NodeType.Document ||\n current.type === NodeType.Element\n ) {\n current.childNodes.forEach(walk);\n }\n }\n\n walk(node);\n}\n\nexport function cleanupSnapshot() {\n // allow a new recording to start numbering nodes from scratch\n _id = 1;\n}\n\nexport default snapshot;\n"],"names":["dom"],"mappings":"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"}
package/dist/record.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const record = require("./record-oACzRSl-.cjs");
3
+ const record = require("./record-BUfdSR_C.cjs");
4
4
  const types = require("./types-B7TTv7Jc.cjs");
5
5
  exports.DEFAULT_MAX_DEPTH = record.DEFAULT_MAX_DEPTH;
6
6
  exports.IGNORED_NODE = record.IGNORED_NODE;
package/dist/record.js CHANGED
@@ -1,4 +1,4 @@
1
- import { D, I, b, c, g, i, n, a, s, t, v, w } from "./record-B2nV9UFB.js";
1
+ import { D, I, b, c, g, i, n, a, s, t, v, w } from "./record-CbT7EKn4.js";
2
2
  import { M, N, o, p, h, e, n as n2, f, l, j, d, g as g2, i as i2, b as b2, k, a as a2, m, r, c as c2, s as s2, t as t2 } from "./types-OLXvwyjP.js";
3
3
  export {
4
4
  D as DEFAULT_MAX_DEPTH,
@@ -556,9 +556,9 @@ var require_types_B7TTv7Jc = __commonJS({
556
556
  }
557
557
  });
558
558
 
559
- // dist/record-oACzRSl-.cjs
560
- var require_record_oACzRSl = __commonJS({
561
- "dist/record-oACzRSl-.cjs"(exports2) {
559
+ // dist/record-BUfdSR_C.cjs
560
+ var require_record_BUfdSR_C = __commonJS({
561
+ "dist/record-BUfdSR_C.cjs"(exports2) {
562
562
  "use strict";
563
563
  var types2 = require_types_B7TTv7Jc();
564
564
  var _id = 1;
@@ -1173,7 +1173,9 @@ var require_record_oACzRSl = __commonJS({
1173
1173
  return true;
1174
1174
  } else if (slimDOMOptions.headFavicon && (sn.tagName === "link" && sn.attributes.rel === "shortcut icon" || sn.tagName === "meta" && (lowerIfExists(sn.attributes.name).match(
1175
1175
  /^msapplication-tile(image|color)$/
1176
- ) || lowerIfExists(sn.attributes.name) === "application-name" || lowerIfExists(sn.attributes.rel) === "icon" || lowerIfExists(sn.attributes.rel) === "apple-touch-icon" || lowerIfExists(sn.attributes.rel) === "shortcut icon"))) {
1176
+ ) || lowerIfExists(sn.attributes.name) === "application-name" || ["icon", "apple-touch-icon", "shortcut icon"].includes(
1177
+ lowerIfExists(sn.attributes.rel)
1178
+ )))) {
1177
1179
  return true;
1178
1180
  } else if (sn.tagName === "meta") {
1179
1181
  if (slimDOMOptions.headMetaDescKeywords && lowerIfExists(sn.attributes.name).match(/^description|keywords$/)) {
@@ -1181,13 +1183,25 @@ var require_record_oACzRSl = __commonJS({
1181
1183
  } else if (slimDOMOptions.headMetaSocial && (lowerIfExists(sn.attributes.property).match(/^(og|twitter|fb):/) || // og = opengraph (facebook)
1182
1184
  lowerIfExists(sn.attributes.name).match(/^(og|twitter):/) || lowerIfExists(sn.attributes.name) === "pinterest")) {
1183
1185
  return true;
1184
- } else if (slimDOMOptions.headMetaRobots && (lowerIfExists(sn.attributes.name) === "robots" || lowerIfExists(sn.attributes.name) === "googlebot" || lowerIfExists(sn.attributes.name) === "bingbot")) {
1186
+ } else if (slimDOMOptions.headMetaRobots && ["robots", "googlebot", "bingbot"].includes(
1187
+ lowerIfExists(sn.attributes.name)
1188
+ )) {
1185
1189
  return true;
1186
1190
  } else if (slimDOMOptions.headMetaHttpEquiv && sn.attributes["http-equiv"] !== void 0) {
1187
1191
  return true;
1188
- } else if (slimDOMOptions.headMetaAuthorship && (lowerIfExists(sn.attributes.name) === "author" || lowerIfExists(sn.attributes.name) === "generator" || lowerIfExists(sn.attributes.name) === "framework" || lowerIfExists(sn.attributes.name) === "publisher" || lowerIfExists(sn.attributes.name) === "progid" || lowerIfExists(sn.attributes.property).match(/^article:/) || lowerIfExists(sn.attributes.property).match(/^product:/))) {
1192
+ } else if (slimDOMOptions.headMetaAuthorship && (["author", "generator", "framework", "publisher", "progid"].includes(
1193
+ lowerIfExists(sn.attributes.name)
1194
+ ) || lowerIfExists(sn.attributes.property).match(/^article:/) || lowerIfExists(sn.attributes.property).match(/^product:/))) {
1189
1195
  return true;
1190
- } else if (slimDOMOptions.headMetaVerification && (lowerIfExists(sn.attributes.name) === "google-site-verification" || lowerIfExists(sn.attributes.name) === "yandex-verification" || lowerIfExists(sn.attributes.name) === "csrf-token" || lowerIfExists(sn.attributes.name) === "p:domain_verify" || lowerIfExists(sn.attributes.name) === "verify-v1" || lowerIfExists(sn.attributes.name) === "verification" || lowerIfExists(sn.attributes.name) === "shopify-checkout-api-token")) {
1196
+ } else if (slimDOMOptions.headMetaVerification && [
1197
+ "google-site-verification",
1198
+ "yandex-verification",
1199
+ "csrf-token",
1200
+ "p:domain_verify",
1201
+ "verify-v1",
1202
+ "verification",
1203
+ "shopify-checkout-api-token"
1204
+ ].includes(lowerIfExists(sn.attributes.name))) {
1191
1205
  return true;
1192
1206
  }
1193
1207
  }
@@ -1440,6 +1454,27 @@ var require_record_oACzRSl = __commonJS({
1440
1454
  }
1441
1455
  return serializedNode;
1442
1456
  }
1457
+ function slimDOMDefaults(slimDOM) {
1458
+ if (slimDOM === true || slimDOM === "all") {
1459
+ return {
1460
+ script: true,
1461
+ comment: true,
1462
+ headFavicon: true,
1463
+ headWhitespace: true,
1464
+ headMetaSocial: true,
1465
+ headMetaRobots: true,
1466
+ headMetaHttpEquiv: true,
1467
+ headMetaVerification: true,
1468
+ headMetaAuthorship: slimDOM === "all",
1469
+ headMetaDescKeywords: slimDOM === "all",
1470
+ headTitleMutations: slimDOM === "all"
1471
+ };
1472
+ }
1473
+ if (slimDOM === false) {
1474
+ return {};
1475
+ }
1476
+ return slimDOM;
1477
+ }
1443
1478
  function snapshot(n, options) {
1444
1479
  const {
1445
1480
  mirror = new types2.Mirror(),
@@ -1484,22 +1519,7 @@ var require_record_oACzRSl = __commonJS({
1484
1519
  } : maskAllInputs === false ? {
1485
1520
  password: true
1486
1521
  } : maskAllInputs;
1487
- const slimDOMOptions = slimDOM === true || slimDOM === "all" ? (
1488
- // if true: set of sensible options that should not throw away any information
1489
- {
1490
- script: true,
1491
- comment: true,
1492
- headFavicon: true,
1493
- headWhitespace: true,
1494
- headMetaDescKeywords: slimDOM === "all",
1495
- // destructive
1496
- headMetaSocial: true,
1497
- headMetaRobots: true,
1498
- headMetaHttpEquiv: true,
1499
- headMetaAuthorship: true,
1500
- headMetaVerification: true
1501
- }
1502
- ) : slimDOM === false ? {} : slimDOM;
1522
+ const slimDOMOptions = slimDOMDefaults(slimDOM);
1503
1523
  return serializeNodeWithId(n, {
1504
1524
  doc: n,
1505
1525
  mirror,
@@ -1548,6 +1568,7 @@ var require_record_oACzRSl = __commonJS({
1548
1568
  exports2.needMaskingText = needMaskingText;
1549
1569
  exports2.resetMaxDepthState = resetMaxDepthState;
1550
1570
  exports2.serializeNodeWithId = serializeNodeWithId;
1571
+ exports2.slimDOMDefaults = slimDOMDefaults;
1551
1572
  exports2.snapshot = snapshot;
1552
1573
  exports2.transformAttribute = transformAttribute;
1553
1574
  exports2.visitSnapshot = visitSnapshot;
@@ -1557,7 +1578,7 @@ var require_record_oACzRSl = __commonJS({
1557
1578
 
1558
1579
  // dist/record.cjs
1559
1580
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
1560
- var record = require_record_oACzRSl();
1581
+ var record = require_record_BUfdSR_C();
1561
1582
  var types = require_types_B7TTv7Jc();
1562
1583
  exports.DEFAULT_MAX_DEPTH = record.DEFAULT_MAX_DEPTH;
1563
1584
  exports.IGNORED_NODE = record.IGNORED_NODE;