feat(compiler): support the three api render-binding forms
- Parse api="name", api="name()", and api="name({ ... })" render bindings
for apis {} (mode "any") blocks, mirroring @click="fn()" syntax.
- Render-bind by calling Task 4's generated server `api` object directly
(api.<name>(args)) rather than re-implementing the fetch/response
transport, spliced into the SSR template via the existing loop/expression
sentinel mechanism so the call runs inside the async render function with
await support.
- A block that is both render-bound and called from code runs twice by
design (no dedup); pinned with a test.
- Fix packages/syntax's attribute-value lexer (readQuoted) to honor
backslash-escaped quotes, needed so an api="..." call expression can
itself contain a quoted string/object literal.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1067,10 +1067,20 @@ export function parseHtmlView(src: string, pos: number): { nodes: ViewNode[]; en
|
||||
const quote = src[i];
|
||||
if (quote !== '"' && quote !== "'") return fail("Expected a quoted attribute value");
|
||||
i++;
|
||||
const start = i;
|
||||
while (i < src.length && src[i] !== quote) i++;
|
||||
// Backslash-escapes the delimiter (and anything else) so an attribute
|
||||
// value -- e.g. an `api="fn({ a: \"b\" })"` call expression -- can carry
|
||||
// the same quote character it's wrapped in.
|
||||
let value = "";
|
||||
while (i < src.length && src[i] !== quote) {
|
||||
if (src[i] === "\\" && i + 1 < src.length) {
|
||||
value += src[i + 1];
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
value += src[i];
|
||||
i++;
|
||||
}
|
||||
if (i >= src.length) return fail("Unterminated attribute value");
|
||||
const value = src.slice(start, i);
|
||||
i++; // closing quote
|
||||
return value;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user