SSR await-then-catch

pull/952/head
Rich Harris 7 years ago
parent 56b167b44f
commit 8a0813e96b

@ -159,6 +159,9 @@ export default function ssr(
};
};
${
// TODO this is a bit hacky
/__escape/.test(generator.renderCode) && deindent`
var escaped = {
'"': '"',
"'": '&##39;',
@ -170,6 +173,16 @@ export default function ssr(
function __escape(html) {
return String(html).replace(/["'&<>]/g, match => escaped[match]);
}
`
}
${
/__isPromise/.test(generator.renderCode) && deindent`
function __isPromise(value) {
return value && typeof value.then === 'function';
}
`
}
`.replace(/(@+|#+|%+)(\w*(?:-\w*)?)/g, (match: string, sigil: string, name: string) => {
if (sigil === '@') return generator.alias(name);
if (sigil === '%') return generator.templateVars.get(name);

@ -10,6 +10,16 @@ const preprocessors = {
RawMustacheTag: noop,
Text: noop,
AwaitBlock: (
generator: SsrGenerator,
node: Node,
elementStack: Node[]
) => {
preprocessChildren(generator, node.pending, elementStack);
preprocessChildren(generator, node.then, elementStack);
preprocessChildren(generator, node.catch, elementStack);
},
IfBlock: (
generator: SsrGenerator,
node: Node,

@ -0,0 +1,40 @@
import visit from '../visit';
import { SsrGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
export default function visitAwaitBlock(
generator: SsrGenerator,
block: Block,
node: Node
) {
block.contextualise(node.expression);
const { dependencies, snippet } = node.metadata;
// TODO should this be the generator's job? It's duplicated between
// here and the equivalent DOM compiler visitor
const contexts = new Map(block.contexts);
contexts.set(node.value, '__value');
const contextDependencies = new Map(block.contextDependencies);
contextDependencies.set(node.value, dependencies);
const childBlock = block.child({
contextDependencies,
contexts
});
generator.append('${(function(__value) { if(__isPromise(__value)) return `');
node.pending.children.forEach((child: Node) => {
visit(generator, childBlock, child);
});
generator.append('`; return `');
node.then.children.forEach((child: Node) => {
visit(generator, childBlock, child);
});
generator.append(`\`;}(${snippet})) }`);
}

@ -1,3 +1,4 @@
import AwaitBlock from './AwaitBlock';
import Comment from './Comment';
import EachBlock from './EachBlock';
import Element from './Element';
@ -7,6 +8,7 @@ import RawMustacheTag from './RawMustacheTag';
import Text from './Text';
export default {
AwaitBlock,
Comment,
EachBlock,
Element,

@ -209,7 +209,7 @@ export default function mustache(parser: Parser) {
value: null,
error: null,
pending: {
start,
start: null,
end: null,
type: 'PendingBlock',
children: []
@ -289,6 +289,7 @@ export default function mustache(parser: Parser) {
parser.stack.push(block);
if (type === 'AwaitBlock') {
block.pending.start = parser.index;
parser.stack.push(block.pending);
}
} else if (parser.eat('yield')) {

@ -22,16 +22,4 @@ SvelteComponent.renderCss = function() {
};
};
var escaped = {
'"': '&quot;',
"'": '&#39;',
'&': '&amp;',
'<': '&lt;',
'>': '&gt;'
};
function __escape(html) {
return String(html).replace(/["'&<>]/g, match => escaped[match]);
}
module.exports = SvelteComponent;
Loading…
Cancel
Save