astro
Version:
Astro is a modern site builder with web best practices, performance, and DX front-of-mind.
26 lines (25 loc) • 996 B
JavaScript
import { ELEMENT_NODE, parse, walkSync } from "ultrahtml";
import { escapeTemplateLiteralCharacters } from "./utils.js";
export const SLOT_PREFIX = `___SLOTS___`;
/**
* Find every `<slot>` (excluding `is:inline` ones) and describe how to replace it
* with a `${___SLOTS___[name] ?? `fallback`}` template literal expression.
*/
export function collectSlots(code) {
const slots = [];
walkSync(parse(code), (node) => {
if (node.type !== ELEMENT_NODE || node.name !== "slot") return;
if ("is:inline" in node.attributes) return;
const [open, close] = node.loc;
if (!close) return;
const name = node.attributes.name ?? "default";
// Empty slots fall back to rendering the slot tag itself
const fallback = open.end < close.start ? code.slice(open.end, close.start) : code.slice(open.start, close.end);
slots.push({
start: open.start,
end: close.end,
value: `\${${SLOT_PREFIX}["${name}"] ?? \`${escapeTemplateLiteralCharacters(fallback).trim()}\`}`
});
});
return slots;
}