{"version":3,"file":"record.cjs","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":["toLowerCase","recompressBase64Image","checkDataURLSize","absolutifyURLs","dom","isElement","NodeType","stringifyStylesheet","maskInputValue","getInputType","is2DCanvasBlank","extractFileExtension","isNativeShadowDom","isShadowRoot","Mirror"],"mappings":"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"}