66 lines
1.7 KiB
JavaScript
66 lines
1.7 KiB
JavaScript
import { HTMLString, markHTMLString } from "../escape.js";
|
|
import { renderChild } from "./any.js";
|
|
const slotString = Symbol.for("astro:slot-string");
|
|
class SlotString extends HTMLString {
|
|
constructor(content, instructions) {
|
|
super(content);
|
|
this.instructions = instructions;
|
|
this[slotString] = true;
|
|
}
|
|
}
|
|
slotString;
|
|
function isSlotString(str) {
|
|
return !!str[slotString];
|
|
}
|
|
async function* renderSlot(result, slotted, fallback) {
|
|
if (slotted) {
|
|
let iterator = renderChild(typeof slotted === "function" ? slotted(result) : slotted);
|
|
yield* iterator;
|
|
}
|
|
if (fallback && !slotted) {
|
|
yield* renderSlot(result, fallback);
|
|
}
|
|
}
|
|
async function renderSlotToString(result, slotted, fallback) {
|
|
let content = "";
|
|
let instructions = null;
|
|
let iterator = renderSlot(result, slotted, fallback);
|
|
for await (const chunk of iterator) {
|
|
if (typeof chunk.type === "string") {
|
|
if (instructions === null) {
|
|
instructions = [];
|
|
}
|
|
instructions.push(chunk);
|
|
} else {
|
|
content += chunk;
|
|
}
|
|
}
|
|
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 };
|
|
}
|
|
export {
|
|
SlotString,
|
|
isSlotString,
|
|
renderSlot,
|
|
renderSlotToString,
|
|
renderSlots
|
|
};
|