{"version":3,"file":"assign-names.mjs","sources":["../../../../src/view/utils/assign-names.ts"],"sourcesContent":["import { ElementOrSelector, resolveElements } from \"../../utils/resolve-elements\"\n\nlet nameCount = 0\n\n/**\n * Generated names live in their own namespace so we can tell a name we own\n * (and must clean up) from an author-defined one - and so a stale generated\n * name left behind by an interrupted transition is re-owned, not mistaken for\n * the author's and leaked.\n */\nconst generatedName = () => `motion-view-${nameCount++}`\n\nconst isGeneratedName = (name: string) => name.startsWith(\"motion-view-\")\n\n/**\n * Tag a captured element with a `view-transition-class` so authors can target\n * its generated layer from CSS (e.g. `::view-transition-group(.hero)`) without\n * the opaque generated name. Tracked in `classed` - separate from the generated\n * names in `assigned` - so cleanup removes the class without ever stripping an\n * author's own inline `view-transition-name`.\n */\nfunction tagClass(\n element: Element,\n className: string | undefined,\n classed: Element[]\n) {\n if (!className) return\n ;(element as HTMLElement).style?.setProperty(\n \"view-transition-class\",\n className\n )\n classed.push(element)\n}\n\n/**\n * Set the element's `view-transition-group` so its layer reconstructs the DOM\n * hierarchy in the pseudo-tree (`contain`) - or stays flat (`none`). Tracked in\n * `grouped` for cleanup. When the element clips (any non-`visible` overflow) its\n * name is recorded in `clipChildren` so the caller can clip the nested children\n * (`::view-transition-group-children(name)`), mirroring the live clip through\n * the whole transition rather than only at the live-DOM handoff.\n *\n * Ignored by browsers without nested view-transition groups, where it harmlessly\n * degrades to the flat default.\n */\nfunction applyGroup(\n element: Element,\n name: string,\n group: string | undefined,\n grouped: Element[],\n clipChildren?: Set\n) {\n if (!group) return\n ;(element as HTMLElement).style?.setProperty(\"view-transition-group\", group)\n grouped.push(element)\n\n if (group !== \"none\" && clipChildren) {\n const style = getComputedStyle(element)\n if (style.overflowX !== \"visible\" || style.overflowY !== \"visible\") {\n clipChildren.add(name)\n }\n }\n}\n\n/**\n * Resolve a selector/Element to elements and ensure each one carries a\n * `view-transition-name` we can target from script.\n *\n * Author-defined names are reused as-is. Elements that are unnamed (or use\n * the browser's `auto`/`match-element`, whose generated name is not exposed\n * to script) are given a unique generated name, set inline so it's captured,\n * and tracked in `assigned` for later cleanup.\n *\n * `registry` maps each Element to its name so the same element keeps its name\n * across both captures (before and after the update), which is what allows a\n * persistent element to animate as a single `group` layer.\n */\nexport function assignViewTransitionNames(\n definition: ElementOrSelector,\n registry: Map,\n assigned: Element[],\n forcedNames?: string[],\n className?: string,\n classed: Element[] = [],\n group?: string,\n grouped: Element[] = [],\n clipChildren?: Set\n): string[] {\n const elements = resolveElements(definition)\n\n /**\n * The new end of a paired morph: give each element the matching name from\n * the old end (by index) so the two share one layer and morph. If the new\n * end resolves to *more* elements than the old end named, the extras have no\n * counterpart - give them a fresh name so they animate as newcomers rather\n * than being silently left unnamed. We return the names actually assigned\n * (sized to the resolved elements), not the raw `forcedNames`, so stagger\n * totals and the layer set stay in step with what's on the page.\n */\n if (forcedNames) {\n return elements.map((element, i) => {\n const existing = registry.get(element)\n if (existing) return existing\n\n const name = forcedNames[i] ?? generatedName()\n ;(element as HTMLElement).style?.setProperty(\n \"view-transition-name\",\n name\n )\n assigned.push(element)\n registry.set(element, name)\n tagClass(element, className, classed)\n applyGroup(element, name, group, grouped, clipChildren)\n\n return name\n })\n }\n\n /**\n * Read every current name up front, before assigning any. Interleaving the\n * reads with the inline `setProperty` writes below would dirty styles\n * between reads and force a style recalc per element; batching the reads\n * keeps it to one. Elements already in the registry keep their name and\n * need no read.\n */\n const currentNames = elements.map((element) =>\n registry.has(element)\n ? undefined\n : getComputedStyle(element).getPropertyValue(\"view-transition-name\")\n )\n\n return elements.map((element, i) => {\n const existing = registry.get(element)\n if (existing) return existing\n\n const current = currentNames[i]\n\n let name: string\n if (\n current &&\n current !== \"none\" &&\n current !== \"auto\" &&\n current !== \"match-element\" &&\n !isGeneratedName(current)\n ) {\n /**\n * The author already named this layer - target it as-is and leave\n * it to them to clean up. `auto`/`match-element` are overridden\n * because their generated name is not exposed to script, and a\n * stale `motion-view-*` (e.g. left by an interrupted transition) is\n * re-owned rather than adopted as an author name and leaked.\n */\n name = current\n } else {\n name = generatedName()\n ;(element as HTMLElement).style?.setProperty(\n \"view-transition-name\",\n name\n )\n assigned.push(element)\n }\n\n registry.set(element, name)\n tagClass(element, className, classed)\n applyGroup(element, name, group, grouped, clipChildren)\n\n return name\n })\n}\n\n/**\n * Remove the `view-transition-name`s we generated and the\n * `view-transition-class`es we applied. Author-defined names are never touched\n * (they're not in `assigned`). Safe to call more than once (e.g. on both a\n * finished and an interrupted transition).\n */\nexport function releaseViewTransitionNames(\n assigned: Element[],\n classed: Element[] = [],\n grouped: Element[] = []\n): void {\n for (const element of assigned) {\n ;(element as HTMLElement).style?.removeProperty(\"view-transition-name\")\n }\n for (const element of classed) {\n ;(element as HTMLElement).style?.removeProperty(\"view-transition-class\")\n }\n for (const element of grouped) {\n ;(element as HTMLElement).style?.removeProperty(\"view-transition-group\")\n }\n}\n"],"names":[],"mappings":"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"}