UNPKG

astro

Version:

Astro is a modern site builder with web best practices, performance, and DX front-of-mind.

87 lines (86 loc) 2.5 kB
import { renderTemplate } from "./astro/render-template.js"; import { HTMLString, markHTMLString, unescapeHTML } from "../escape.js"; import { renderChild } from "./any.js"; import { chunkToString } from "./common.js"; const slotString = Symbol.for("astro:slot-string"); class SlotString extends HTMLString { instructions; [slotString]; constructor(content, instructions) { super(content); this.instructions = instructions; this[slotString] = true; } } function isSlotString(str) { return !!str[slotString]; } function renderSlot(result, slotted, fallback) { if (!slotted && fallback) { return renderSlot(result, fallback); } return { async render(destination) { await renderChild(destination, typeof slotted === "function" ? slotted(result) : slotted); } }; } async function renderSlotToString(result, slotted, fallback) { let content = ""; let instructions = null; const temporaryDestination = { write(chunk) { if (chunk instanceof SlotString) { content += chunk; if (chunk.instructions) { instructions ??= []; instructions.push(...chunk.instructions); } } else if (chunk instanceof Response) return; else if (typeof chunk === "object" && "type" in chunk && typeof chunk.type === "string") { if (instructions === null) { instructions = []; } instructions.push(chunk); } else { content += chunkToString(result, chunk); } } }; const renderInstance = renderSlot(result, slotted, fallback); await renderInstance.render(temporaryDestination); return markHTMLString(new SlotString(content, instructions)); } async function renderSlots(result, slots = {}) { let slotInstructions = null; let children = {}; if (slots) { await Promise.all( Object.entries(slots).map( ([key, value]) => renderSlotToString(result, value).then((output) => { if (output.instructions) { if (slotInstructions === null) { slotInstructions = []; } slotInstructions.push(...output.instructions); } children[key] = output; }) ) ); } return { slotInstructions, children }; } function createSlotValueFromString(content) { return function() { return renderTemplate`${unescapeHTML(content)}`; }; } export { SlotString, createSlotValueFromString, isSlotString, renderSlot, renderSlotToString, renderSlots };