{"version":3,"file":"headContentUtils.cjs","names":["Solid","appendUniqueUserTags","escapeHtml","getAssetCrossOrigin","getScriptPreloadAttrs","resolveManifestCssLink","useRouter","AssetCrossOriginConfig","RouterManagedTag","useTags","assetCrossOrigin","router","nonce","options","ssr","activeMatches","createMemo","stores","matches","get","routeMeta","map","match","meta","filter","undefined","Accessor","Array","resultMeta","metaByAttribute","Record","title","routeMetasArray","i","length","metas","j","m","tag","children","json","JSON","stringify","push","attrs","type","attribute","name","property","content","reverse","links","constructed","flatMap","link","manifestCssTags","manifest","tags","routes","routeId","css","forEach","resolvedLink","rel","crossOrigin","inlineStyle","inlineCss","preloadLinks","preloads","Boolean","preload","styles","style","headScripts","script","prev","next","replaceEqualTags","prevByKey","Map","set","isEqual","result","index","existing"],"sources":["../../src/headContentUtils.tsx"],"sourcesContent":["import * as Solid from 'solid-js'\nimport {\n  appendUniqueUserTags,\n  escapeHtml,\n  getAssetCrossOrigin,\n  getScriptPreloadAttrs,\n  resolveManifestCssLink,\n} from '@tanstack/router-core'\nimport { useRouter } from './useRouter'\nimport type {\n  AssetCrossOriginConfig,\n  RouterManagedTag,\n} from '@tanstack/router-core'\n\n/**\n * Build the list of head/link/meta/script tags to render for active matches.\n * Used internally by `HeadContent`.\n */\nexport const useTags = (assetCrossOrigin?: AssetCrossOriginConfig) => {\n  const router = useRouter()\n  const nonce = router.options.ssr?.nonce\n  const activeMatches = Solid.createMemo(() => router.stores.matches.get())\n  const routeMeta = Solid.createMemo(() =>\n    activeMatches()\n      .map((match) => match.meta)\n      .filter((meta) => meta !== undefined),\n  )\n\n  const meta: Solid.Accessor<Array<RouterManagedTag>> = Solid.createMemo(() => {\n    const resultMeta: Array<RouterManagedTag> = []\n    const metaByAttribute: Record<string, true> = {}\n    let title: RouterManagedTag | undefined\n    const routeMetasArray = routeMeta()\n    for (let i = routeMetasArray.length - 1; i >= 0; i--) {\n      const metas = routeMetasArray[i]!\n      for (let j = metas.length - 1; j >= 0; j--) {\n        const m = metas[j]\n        if (!m) continue\n\n        if (m.title) {\n          if (!title) {\n            title = {\n              tag: 'title',\n              children: m.title,\n            }\n          }\n        } else if ('script:ld+json' in m) {\n          // Handle JSON-LD structured data\n          // Content is HTML-escaped to prevent XSS when injected via innerHTML\n          try {\n            const json = JSON.stringify(m['script:ld+json'])\n            resultMeta.push({\n              tag: 'script',\n              attrs: {\n                type: 'application/ld+json',\n              },\n              children: escapeHtml(json),\n            })\n          } catch {\n            // Skip invalid JSON-LD objects\n          }\n        } else {\n          const attribute = m.name ?? m.property\n          if (attribute) {\n            if (metaByAttribute[attribute]) {\n              continue\n            } else {\n              metaByAttribute[attribute] = true\n            }\n          }\n\n          resultMeta.push({\n            tag: 'meta',\n            attrs: {\n              ...m,\n              nonce,\n            },\n          })\n        }\n      }\n    }\n\n    if (title) {\n      resultMeta.push(title)\n    }\n\n    if (router.options.ssr?.nonce) {\n      resultMeta.push({\n        tag: 'meta',\n        attrs: {\n          property: 'csp-nonce',\n          content: router.options.ssr.nonce,\n        },\n      })\n    }\n    resultMeta.reverse()\n\n    return resultMeta\n  })\n\n  const links = Solid.createMemo(() => {\n    const matches = activeMatches()\n    const constructed = matches\n      .flatMap((match) => match.links ?? [])\n      .filter((link) => link !== undefined)\n      .map((link) => ({\n        tag: 'link',\n        attrs: {\n          ...link,\n          nonce,\n        },\n      })) satisfies Array<RouterManagedTag>\n\n    return constructed\n  })\n\n  const manifestCssTags = Solid.createMemo(() => {\n    const manifest = router.ssr?.manifest\n    const tags: Array<RouterManagedTag> = []\n\n    if (!manifest) {\n      return tags\n    }\n\n    for (const match of activeMatches()) {\n      manifest.routes[match.routeId]?.css?.forEach((link) => {\n        const resolvedLink = resolveManifestCssLink(link)\n        tags.push({\n          tag: 'link',\n          attrs: {\n            rel: 'stylesheet',\n            ...resolvedLink,\n            crossOrigin:\n              getAssetCrossOrigin(assetCrossOrigin, 'stylesheet') ??\n              resolvedLink.crossOrigin,\n            nonce,\n          },\n        })\n      })\n    }\n\n    if (manifest.inlineStyle) {\n      tags.push({\n        tag: 'style',\n        attrs: {\n          ...manifest.inlineStyle.attrs,\n          nonce,\n        },\n        children: manifest.inlineStyle.children,\n        inlineCss: true,\n      })\n    }\n\n    return tags\n  })\n\n  const preloadLinks = Solid.createMemo(() => {\n    const matches = activeMatches()\n    const preloadLinks: Array<RouterManagedTag> = []\n\n    matches.forEach((match) =>\n      router.ssr?.manifest?.routes[match.routeId]?.preloads\n        ?.filter(Boolean)\n        .forEach((preload) => {\n          preloadLinks.push({\n            tag: 'link',\n            attrs: {\n              ...getScriptPreloadAttrs(\n                router.ssr?.manifest,\n                preload,\n                assetCrossOrigin,\n              ),\n              nonce,\n            },\n          })\n        }),\n    )\n\n    return preloadLinks\n  })\n\n  const styles = Solid.createMemo(() => {\n    return activeMatches()\n      .flatMap((match) => match.styles ?? [])\n      .filter((style) => style !== undefined)\n      .map(({ children, ...style }) => ({\n        tag: 'style',\n        attrs: {\n          ...style,\n          nonce,\n        },\n        children: children as string | undefined,\n      })) satisfies Array<RouterManagedTag>\n  })\n\n  const headScripts = Solid.createMemo(() => {\n    return activeMatches()\n      .flatMap((match) => match.headScripts ?? [])\n      .filter((script) => script !== undefined)\n      .map(({ children, ...script }) => ({\n        tag: 'script',\n        attrs: {\n          ...script,\n          nonce,\n        },\n        children: children as string | undefined,\n      })) satisfies Array<RouterManagedTag>\n  })\n\n  return Solid.createMemo((prev: Array<RouterManagedTag> | undefined) => {\n    const next: Array<RouterManagedTag> = []\n    appendUniqueUserTags(next, meta())\n    next.push(...preloadLinks())\n    appendUniqueUserTags(next, links())\n    next.push(...manifestCssTags())\n    appendUniqueUserTags(next, styles())\n    appendUniqueUserTags(next, headScripts())\n\n    if (prev === undefined) {\n      return next\n    }\n    return replaceEqualTags(prev, next)\n  })\n}\n\nfunction replaceEqualTags(\n  prev: Array<RouterManagedTag>,\n  next: Array<RouterManagedTag>,\n) {\n  const prevByKey = new Map<string, RouterManagedTag>()\n  for (const tag of prev) {\n    prevByKey.set(JSON.stringify(tag), tag)\n  }\n\n  let isEqual = prev.length === next.length\n  const result = next.map((tag, index) => {\n    const existing = prevByKey.get(JSON.stringify(tag))\n    if (existing) {\n      if (existing !== prev[index]) {\n        isEqual = false\n      }\n      return existing\n    }\n\n    isEqual = false\n    return tag\n  })\n\n  return isEqual ? prev : result\n}\n"],"mappings":"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"}