SSR await-then-catch

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

@ -159,16 +159,29 @@ export default function ssr(
}; };
}; };
var escaped = { ${
'"': '"', // TODO this is a bit hacky
"'": '&##39;', /__escape/.test(generator.renderCode) && deindent`
'&': '&', var escaped = {
'<': '&lt;', '"': '&quot;',
'>': '&gt;' "'": '&##39;',
}; '&': '&amp;',
'<': '&lt;',
'>': '&gt;'
};
function __escape(html) {
return String(html).replace(/["'&<>]/g, match => escaped[match]);
}
`
}
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) => { `.replace(/(@+|#+|%+)(\w*(?:-\w*)?)/g, (match: string, sigil: string, name: string) => {
if (sigil === '@') return generator.alias(name); if (sigil === '@') return generator.alias(name);

@ -10,6 +10,16 @@ const preprocessors = {
RawMustacheTag: noop, RawMustacheTag: noop,
Text: 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: ( IfBlock: (
generator: SsrGenerator, generator: SsrGenerator,
node: Node, 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 Comment from './Comment';
import EachBlock from './EachBlock'; import EachBlock from './EachBlock';
import Element from './Element'; import Element from './Element';
@ -7,6 +8,7 @@ import RawMustacheTag from './RawMustacheTag';
import Text from './Text'; import Text from './Text';
export default { export default {
AwaitBlock,
Comment, Comment,
EachBlock, EachBlock,
Element, Element,

@ -209,7 +209,7 @@ export default function mustache(parser: Parser) {
value: null, value: null,
error: null, error: null,
pending: { pending: {
start, start: null,
end: null, end: null,
type: 'PendingBlock', type: 'PendingBlock',
children: [] children: []
@ -289,6 +289,7 @@ export default function mustache(parser: Parser) {
parser.stack.push(block); parser.stack.push(block);
if (type === 'AwaitBlock') { if (type === 'AwaitBlock') {
block.pending.start = parser.index;
parser.stack.push(block.pending); parser.stack.push(block.pending);
} }
} else if (parser.eat('yield')) { } 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; module.exports = SvelteComponent;
Loading…
Cancel
Save