import { HTMLString, markHTMLString } from "../escape.js"; import { serializeListValue } from "../util.js"; const voidElementNames = /^(area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/i; const htmlBooleanAttributes = /^(allowfullscreen|async|autofocus|autoplay|controls|default|defer|disabled|disablepictureinpicture|disableremoteplayback|formnovalidate|hidden|loop|nomodule|novalidate|open|playsinline|readonly|required|reversed|scoped|seamless|itemscope)$/i; const htmlEnumAttributes = /^(contenteditable|draggable|spellcheck|value)$/i; const svgEnumAttributes = /^(autoReverse|externalResourcesRequired|focusable|preserveAlpha)$/i; const STATIC_DIRECTIVES = /* @__PURE__ */ new Set(["set:html", "set:text"]); const toIdent = (k) => k.trim().replace(/(?:(?!^)\b\w|\s+|[^\w]+)/g, (match, index) => { if (/[^\w]|\s/.test(match)) return ""; return index === 0 ? match : match.toUpperCase(); }); const toAttributeString = (value, shouldEscape = true) => shouldEscape ? String(value).replace(/&/g, "&").replace(/"/g, """) : value; const kebab = (k) => k.toLowerCase() === k ? k : k.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`); const toStyleString = (obj) => Object.entries(obj).map(([k, v]) => { if (k[0] !== "-" && k[1] !== "-") return `${kebab(k)}:${v}`; if (kebab(k) !== k) return `${kebab(k)}:var(${k});${k}:${v}`; return `${k}:${v}`; }).join(";"); function defineScriptVars(vars) { var _a; let output = ""; for (const [key, value] of Object.entries(vars)) { output += `const ${toIdent(key)} = ${(_a = JSON.stringify(value)) == null ? void 0 : _a.replace( /<\/script>/g, "\\x3C/script>" )}; `; } return markHTMLString(output); } function formatList(values) { if (values.length === 1) { return values[0]; } return `${values.slice(0, -1).join(", ")} or ${values[values.length - 1]}`; } function addAttribute(value, key, shouldEscape = true) { if (value == null) { return ""; } if (value === false) { if (htmlEnumAttributes.test(key) || svgEnumAttributes.test(key)) { return markHTMLString(` ${key}="false"`); } return ""; } if (STATIC_DIRECTIVES.has(key)) { console.warn(`[astro] The "${key}" directive cannot be applied dynamically at runtime. It will not be rendered as an attribute. Make sure to use the static attribute syntax (\`${key}={value}\`) instead of the dynamic spread syntax (\`{...{ "${key}": value }}\`).`); return ""; } if (key === "class:list") { const listValue = toAttributeString(serializeListValue(value), shouldEscape); if (listValue === "") { return ""; } return markHTMLString(` ${key.slice(0, -5)}="${listValue}"`); } if (key === "style" && !(value instanceof HTMLString)) { if (Array.isArray(value) && value.length === 2) { return markHTMLString( ` ${key}="${toAttributeString(`${toStyleString(value[0])};${value[1]}`, shouldEscape)}"` ); } if (typeof value === "object") { return markHTMLString(` ${key}="${toAttributeString(toStyleString(value), shouldEscape)}"`); } } if (key === "className") { return markHTMLString(` class="${toAttributeString(value, shouldEscape)}"`); } if (value === true && (key.startsWith("data-") || htmlBooleanAttributes.test(key))) { return markHTMLString(` ${key}`); } else { return markHTMLString(` ${key}="${toAttributeString(value, shouldEscape)}"`); } } function internalSpreadAttributes(values, shouldEscape = true) { let output = ""; for (const [key, value] of Object.entries(values)) { output += addAttribute(value, key, shouldEscape); } return markHTMLString(output); } function renderElement(name, { props: _props, children = "" }, shouldEscape = true) { const { lang: _, "data-astro-id": astroId, "define:vars": defineVars, ...props } = _props; if (defineVars) { if (name === "style") { delete props["is:global"]; delete props["is:scoped"]; } if (name === "script") { delete props.hoist; children = defineScriptVars(defineVars) + "\n" + children; } } if ((children == null || children == "") && voidElementNames.test(name)) { return `<${name}${internalSpreadAttributes(props, shouldEscape)} />`; } return `<${name}${internalSpreadAttributes(props, shouldEscape)}>${children}`; } const iteratorQueue = []; function queueIteratorBuffers(iterators) { if (iteratorQueue.length === 0) { setTimeout(() => { iteratorQueue.forEach((its) => its.forEach((it) => !it.isStarted() && it.buffer())); iteratorQueue.length = 0; }); } iteratorQueue.push(iterators); } function bufferIterators(iterators) { const eagerIterators = iterators.map((it) => new EagerAsyncIterableIterator(it)); queueIteratorBuffers(eagerIterators); return eagerIterators; } class EagerAsyncIterableIterator { #iterable; #queue = new Queue(); #error = void 0; #next; /** * Whether the proxy is running in buffering or pass-through mode */ #isBuffering = false; #gen = void 0; #isStarted = false; constructor(iterable) { this.#iterable = iterable; } /** * Starts to eagerly fetch the inner iterator and cache the results. * Note: This might not be called after next() has been called once, e.g. the iterator is started */ async buffer() { if (this.#gen) { throw new Error("Cannot not switch from non-buffer to buffer mode"); } this.#isBuffering = true; this.#isStarted = true; this.#gen = this.#iterable[Symbol.asyncIterator](); let value = void 0; do { this.#next = this.#gen.next(); try { value = await this.#next; this.#queue.push(value); } catch (e) { this.#error = e; } } while (value && !value.done); } async next() { if (this.#error) { throw this.#error; } if (!this.#isBuffering) { if (!this.#gen) { this.#isStarted = true; this.#gen = this.#iterable[Symbol.asyncIterator](); } return await this.#gen.next(); } if (!this.#queue.isEmpty()) { return this.#queue.shift(); } await this.#next; return this.#queue.shift(); } isStarted() { return this.#isStarted; } [Symbol.asyncIterator]() { return this; } } class Queue { constructor() { this.head = void 0; this.tail = void 0; } push(item) { if (this.head === void 0) { this.head = { item }; this.tail = this.head; } else { this.tail.next = { item }; this.tail = this.tail.next; } } isEmpty() { return this.head === void 0; } shift() { var _a, _b; const val = (_a = this.head) == null ? void 0 : _a.item; this.head = (_b = this.head) == null ? void 0 : _b.next; return val; } } export { EagerAsyncIterableIterator, addAttribute, bufferIterators, defineScriptVars, formatList, internalSpreadAttributes, renderElement, toAttributeString, voidElementNames };