Next.js website for Rocky Mountain Vending company featuring: - Product catalog with Stripe integration - Service areas and parts pages - Admin dashboard with Clerk authentication - SEO optimized pages with JSON-LD structured data Co-authored-by: Cursor <cursoragent@cursor.com>
1 line
No EOL
8.1 KiB
Text
1 line
No EOL
8.1 KiB
Text
{"version":3,"sources":["../../src/client/head-manager.ts"],"sourcesContent":["import { setAttributesFromProps } from './set-attributes-from-props'\n\nimport type { JSX } from 'react'\n\nfunction reactElementToDOM({ type, props }: JSX.Element): HTMLElement {\n const el: HTMLElement = document.createElement(type)\n setAttributesFromProps(el, props)\n\n const { children, dangerouslySetInnerHTML } = props\n if (dangerouslySetInnerHTML) {\n el.innerHTML = dangerouslySetInnerHTML.__html || ''\n } else if (children) {\n el.textContent =\n typeof children === 'string'\n ? children\n : Array.isArray(children)\n ? children.join('')\n : ''\n }\n return el\n}\n\n/**\n * When a `nonce` is present on an element, browsers such as Chrome and Firefox strip it out of the\n * actual HTML attributes for security reasons *when the element is added to the document*. Thus,\n * given two equivalent elements that have nonces, `Element,isEqualNode()` will return false if one\n * of those elements gets added to the document. Although the `element.nonce` property will be the\n * same for both elements, the one that was added to the document will return an empty string for\n * its nonce HTML attribute value.\n *\n * This custom `isEqualNode()` function therefore removes the nonce value from the `newTag` before\n * comparing it to `oldTag`, restoring it afterwards.\n *\n * For more information, see:\n * https://bugs.chromium.org/p/chromium/issues/detail?id=1211471#c12\n */\nexport function isEqualNode(oldTag: Element, newTag: Element) {\n if (oldTag instanceof HTMLElement && newTag instanceof HTMLElement) {\n const nonce = newTag.getAttribute('nonce')\n // Only strip the nonce if `oldTag` has had it stripped. An element's nonce attribute will not\n // be stripped if there is no content security policy response header that includes a nonce.\n if (nonce && !oldTag.getAttribute('nonce')) {\n const cloneTag = newTag.cloneNode(true) as typeof newTag\n cloneTag.setAttribute('nonce', '')\n cloneTag.nonce = nonce\n return nonce === oldTag.nonce && oldTag.isEqualNode(cloneTag)\n }\n }\n\n return oldTag.isEqualNode(newTag)\n}\n\nfunction updateElements(type: string, components: JSX.Element[]) {\n const headEl = document.querySelector('head')\n if (!headEl) return\n\n const oldTags = new Set(headEl.querySelectorAll(`${type}[data-next-head]`))\n\n if (type === 'meta') {\n const metaCharset = headEl.querySelector('meta[charset]')\n if (metaCharset !== null) {\n oldTags.add(metaCharset)\n }\n }\n\n const newTags: Element[] = []\n for (let i = 0; i < components.length; i++) {\n const component = components[i]\n const newTag = reactElementToDOM(component)\n newTag.setAttribute('data-next-head', '')\n\n let isNew = true\n for (const oldTag of oldTags) {\n if (isEqualNode(oldTag, newTag)) {\n oldTags.delete(oldTag)\n isNew = false\n break\n }\n }\n\n if (isNew) {\n newTags.push(newTag)\n }\n }\n\n for (const oldTag of oldTags) {\n oldTag.parentNode?.removeChild(oldTag)\n }\n\n for (const newTag of newTags) {\n // meta[charset] must be first element so special case\n if (\n newTag.tagName.toLowerCase() === 'meta' &&\n newTag.getAttribute('charset') !== null\n ) {\n headEl.prepend(newTag)\n }\n headEl.appendChild(newTag)\n }\n}\n\nexport default function initHeadManager(): {\n mountedInstances: Set<unknown>\n updateHead: (head: JSX.Element[]) => void\n} {\n return {\n mountedInstances: new Set(),\n updateHead: (head: JSX.Element[]) => {\n const tags: Record<string, JSX.Element[]> = {}\n\n head.forEach((h) => {\n if (\n // If the font tag is loaded only on client navigation\n // it won't be inlined. In this case revert to the original behavior\n h.type === 'link' &&\n h.props['data-optimized-fonts']\n ) {\n if (\n document.querySelector(`style[data-href=\"${h.props['data-href']}\"]`)\n ) {\n return\n } else {\n h.props.href = h.props['data-href']\n h.props['data-href'] = undefined\n }\n }\n\n const components = tags[h.type] || []\n components.push(h)\n tags[h.type] = components\n })\n\n const titleComponent = tags.title ? tags.title[0] : null\n let title = ''\n if (titleComponent) {\n const { children } = titleComponent.props\n title =\n typeof children === 'string'\n ? children\n : Array.isArray(children)\n ? children.join('')\n : ''\n }\n if (title !== document.title) document.title = title\n ;['meta', 'base', 'link', 'style', 'script'].forEach((type) => {\n updateElements(type, tags[type] || [])\n })\n },\n }\n}\n"],"names":["setAttributesFromProps","reactElementToDOM","type","props","el","document","createElement","children","dangerouslySetInnerHTML","innerHTML","__html","textContent","Array","isArray","join","isEqualNode","oldTag","newTag","HTMLElement","nonce","getAttribute","cloneTag","cloneNode","setAttribute","updateElements","components","headEl","querySelector","oldTags","Set","querySelectorAll","metaCharset","add","newTags","i","length","component","isNew","delete","push","parentNode","removeChild","tagName","toLowerCase","prepend","appendChild","initHeadManager","mountedInstances","updateHead","head","tags","forEach","h","href","undefined","titleComponent","title"],"mappings":"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","ignoreList":[0]} |